GDSense how-to guide

Godot TileMapLayer: Coordinates, Tiles, and Collision

Set up a TileMapLayer, convert mouse positions to map cells correctly, place known atlas tiles, and separate collision problems from coordinate mistakes.

Published Updated

All documentation guides

The short answer

Use TileMapLayer for a new Godot 4.7 tile-based level, with a TileSet that defines the tiles and their data. Convert positions into the layer’s local space before calling local_to_map(), and use map_to_local() when you need a cell center. Tile placement, visual layers, and collision each have separate settings; verify one at a time.

Should I use TileMap or TileMapLayer?

For a new level in the documented Godot target, use TileMapLayer. The older TileMap node is deprecated. Each TileMapLayer represents one layer, so separate ground, obstacles, and decoration into separate nodes when they need different behavior. A tutorial using a layer-index parameter on TileMap is not interchangeable with the TileMapLayer API.

Start with a small test level rather than migrating an entire world. Create a Node2D root and a TileMapLayer child, assign a TileSet, add an atlas source for your texture, and create a few tiles. Confirm those tiles paint correctly in the editor before introducing procedural code.

Godot TileMapLayer class reference

What must exist before a script can place a tile?

A placement request identifies a TileSet source, an atlas coordinate, and an alternative tile. These are identifiers from your actual TileSet, not numbers to copy blindly from a tutorial. Paint the desired tile manually first, inspect its source and atlas coordinates, and use those same identifiers in the script.

Keep the original TileSet backed up before changing atlas layout or shared resources. A TileSet can be shared by several levels, so an atlas edit may affect more than the scene currently open. Ask an assistant to inspect the resource relationship before reorganizing it.

  • The TileMapLayer has a TileSet assigned.
  • The TileSet has the expected tile size and a texture atlas source.
  • The chosen atlas coordinate contains a created tile, not just a texture region.
  • The source ID and alternative ID match that resource.
  • The tile renders when painted manually in the intended layer.
Godot TileSet setup tutorial

How do I convert a mouse position into a tile cell?

The mouse position in the world and a coordinate inside the layer are different spaces. This example converts the global mouse position with to_local() before finding the cell. It prints the clicked cell and its global center without changing the map, which makes it a useful first diagnostic.

Attach to the TileMapLayer and click the running level
extends TileMapLayer

func _unhandled_input(event: InputEvent) -> void:
    if event is InputEventMouseButton:
        if event.pressed and event.button_index == MOUSE_BUTTON_LEFT:
            var local_mouse: Vector2 = to_local(get_global_mouse_position())
            var cell: Vector2i = local_to_map(local_mouse)
            var global_center: Vector2 = to_global(map_to_local(cell))
            print("Cell: ", cell, " Global center: ", global_center)
  • Click several adjacent cells and confirm the coordinates change one cell at a time.
  • Move the TileMapLayer node away from the origin and repeat.
  • Move or zoom the Camera2D and repeat.
  • If a UI Control consumes the click, test outside that Control before changing coordinate math.

How do I place or erase a known atlas tile?

Once coordinate conversion works, add a small placement function to the same script. The values below are an explicit fixture: source 0 must contain a tile at atlas position (1, 0), with alternative 0. Substitute the values from your TileSet. This example is a single placement, not terrain painting or a complete level editor.

Additional methods in the same TileMapLayer script
func paint_known_tile(cell: Vector2i) -> void:
    set_cell(cell, 0, Vector2i(1, 0), 0)

func clear_tile(cell: Vector2i) -> void:
    erase_cell(cell)

Keep in mind: Do not multiply map coordinates by tile size to guess a global position. That shortcut breaks under transforms and different map layouts; use the layer’s conversion methods.

Why do painted tiles look correct but have no collision?

A visible tile is not proof of a physics shape. Check the TileSet physics layer and each tile’s collision polygon, the TileMapLayer collision setting, and the moving body’s collision layer/mask relationship. Test a single wall tile with visible collision shapes enabled before inspecting the whole map.

Terrain connections are another separate concern: they require configured terrain data and suitable neighboring tile combinations. If plain set_cell placement works but terrain painting does not, inspect the TileSet terrain setup rather than rewriting your mouse-coordinate code.

Godot tile-map editing and layer behavior

What should I attach when asking GDSense about a tile map?

Share the placement script, scene hierarchy, and the relevant TileSet details as text. Name the exact node class and describe whether the problem is a wrong cell, invisible tile, missing collision, or a terrain mismatch. GDSense currently accepts text context, not image attachments: paste the actual tile IDs, Inspector settings, and error messages instead of relying on a screenshot.

@scene provides hierarchy and optional associated scripts, not a full Inspector-property dump. Paste the relevant TileSet settings or attach a reviewed text .tscn/.tres file with @file when saved property values matter. Remove secrets and unrelated content before sharing.

Coordinate debugging request
@openscript
@scene res://levels/tile_test.tscn --scripts
This node is TileMapLayer in Godot 4.7. Clicks select the wrong cell after moving the layer.
Trace the global/local/map conversions. Preserve my TileSet and source IDs.
Suggest the smallest fix and checks with a moved layer and zoomed camera.

Try this workflow inside Godot

Use GDSense to ask questions, attach the context you choose, and review proposed changes without leaving the editor.