Is it possible to see where a tile is being used in a tilemap?

Is there some way to easily see where a given tile is being used in a tilemap. Like highlighting all places where a given tile is used somehow?

The closest I can find so far is hover over a tile and look in in the lower left corner of the screen to see what it’s index is. Remember that index then hover over the tilemap itself and hold down CTRL to show tile indices. Then hunt around manually hoping to find all the places where the tile of that index is used before I forget what the index is.

If I understand your meaning right, I think you could make a tool with a Lua script. I don’t know of a built-in method.

Test image is from More NES-like Tiles | OpenGameArt.org .

As a start, see the script below. It checks the range of tiles in the color bar, then creates a selection on the sprite canvas for the tile map at the current frame.

local sprite = app.sprite
if not sprite then return end

local frame = app.frame
if not frame then return end

local layer = app.layer
if not layer then return end
if not layer.isTilemap then return end

local tileSet = layer.tileset
if not tileSet then return end

local cel = layer:cel(frame)
if not cel then return end

local range = app.range
if range.sprite ~= sprite then return end

local rangeTiles = range.tiles
local lenRangeTiles = #rangeTiles
if lenRangeTiles <= 0 then return end

local tileMap = cel.image
local tileMapPos = cel.position
local xtlTileMap = tileMapPos.x
local ytlTileMap = tileMapPos.y

local tileSetGrid = tileSet.grid
local tileSize = tileSetGrid.tileSize
local wTile = math.max(1, math.abs(tileSize.width))
local hTile = math.max(1, math.abs(tileSize.height))

---key: tile map index
---value: array of 2d coordinates converted to 1d
---as in i = y * w + x, x = i % w, y = i // w .
---@type table<integer, integer[]>
local auditTileMap = {}

local wTileMap = tileMap.width
local itr = tileMap:pixels()
for pixel in itr do
    local entryTileMap = pixel()
    local indexTileMap = app.pixelColor.tileI(entryTileMap)

    if auditTileMap[indexTileMap] then
        local arr = auditTileMap[indexTileMap]
        arr[#arr + 1] = pixel.y * wTileMap + pixel.x
    else
        auditTileMap[indexTileMap] = { pixel.y * wTileMap + pixel.x }
    end
end

local targetSelect = Selection()
local tileRect = Rectangle(0, 0, wTile, hTile)

local j = 0
while j < lenRangeTiles do
    j = j + 1
    local rangeTileEntry = rangeTiles[j]
    local rangeTileIndex = app.pixelColor.tileI(rangeTileEntry)
    local auditMatch = auditTileMap[rangeTileIndex]
    if auditMatch then
        local lenAuditMatch = #auditMatch
        local k = 0
        while k < lenAuditMatch do
            k = k + 1
            local indexTileMap = auditMatch[k]
            local xLocalTileMap = indexTileMap % wTileMap
            local yLocalTileMap = indexTileMap // wTileMap
            tileRect.x = xtlTileMap + xLocalTileMap * wTile
            tileRect.y = ytlTileMap + yLocalTileMap * hTile
            targetSelect:add(tileRect)
        end
    end
end

if not targetSelect.isEmpty then
    sprite.selection = targetSelect
end
app.refresh()

There are many things the example above doesn’t account for, such as any tile flips (X, Y, diagonal) on the tile map you may want to isolate. Nor does it resort to the active foreground tile (or background) when the color bar range is empty. And a dialog UI of course.

A longer term version from which the simplified script above was made is at a Github code repo here. There’s a Youtube video demo for its usage; it’s old, but hopefully gets the idea across.