Feature/script request: Remap tiles based on a map

Sometimes, you realize you want to resize your tileset and/or rearrange the tiles into a more convenient layout. Tiled currently has the ability to update the tileIDs used in a map if the image is resized*, but no support for rearranging tiles.

* Side question

To be honest, I’m reluctant to use the current remapping feature because I haven’t found documentation on the conditions necessary to trigger it. If I have many maps using an external tileset that I want to resize, what are the exact steps I need to take to make sure they’re all updated?

I want to propose an approach that a remapping feature or script could take to make these tasks easier.

Part 1: Making the rearrangements

Tiled already has a great interface for (re)arranging tilesets: the map editor.

If we take our old tileset(s) and place all the tiles onto a single layer in a map in the new arrangement we want, the result is essentially a new tileset. Tiled even allows us to export it as an image! The resulting map file also contains a mapping from the old tileset(s) to the new one - the cell ID is the new tile ID, and the tileID within that cell is the old tile ID. I will refer to this map file as the “conversion map” from here on.

Part 2: Making the new tileset

From the conversion map, we can generate a new tileset, since we know what each tile is and can access its properties from the source tileset(s). The tool/script should generate the image (i.e. do Export As Image on the conversion map, but with a transparent background to preserve tile transparency) and a new tileset tile, which will reference that image. This tileset file should ideally contain collision data for the tiles, animations, terrains, etc.

Implementation notes
  • The user should be prompted for the image name/location first, so that this info can be used in the resulting tileset.
  • If using multiple source tilesets and some Terrains or Wang sets have the same names, they could be differentiated with the original tileset name in parentheses.
  • If the same tile appears more than once in the map, only the first instance of it should get any data attached to it. The subsequent instances should be treated as essentially blank.
  • The map should only have one tile layer. If it has multiple tile layers, the generation process should not proceed, and the user should get a warning. Non-tile layers should be ignored.
  • If set, the map’s background colour should serve as the new tileset’s background colour. If not set and all the source tilesets use the same colour, then that colour should be used as the new tileset’s background colour. If it’s not set and the tilesets use different background colours, then leave it unset.

Part 3: Updating maps to the new tileset

With the conversion map and new tileset in hand, we can now take any map that uses the source tileset(s) and remap it to use the new tileset. This could take the form of a “Remap tiles…” dialog, which lets you select the conversion map and new map files, and applies the remapping to the current active map.

Implementation notes
  • If the conversion map doesn’t use any of the same tilesets as the map, then no remapping should happen, and the user should be informed of this.
  • Optional: attempt to match embedded tilesets to the tilesets used by the conversion map by looking at their image filenames. If this is implemented, the user should be prompted whether they want to do this, as the result would leave their map with an external tileset instead of the embedded one(s).
  • The source tileIDs will possibly not match the map’s tileIDs, since the map may have the tilesets in a different order, may use additional tilesets, etc. Care has to be taken to make sure the right tile IDs are used and replaced. Fortunately, all the data we need IS there - don’t forget that the conversion map still holds references to the source tilesets, the same source tilesets used as on the map.
  • The conversion map should only have one tile layer. If it contains multiple tile layers, then the user likely made a mistake. The conversion process should abort with a warning. Non-tile layers should be ignored.
  • It’s acceptable if the conversion map has fewer or more tiles than the source tileset(s), since the user may choose to add some blank tiles and leave some tiles out. If a tile is found in the map that is used in the source tileset(s) but isn’t used in the conversion map, it should be made empty. If a tile appears multiple times in the conversion map, only the first instance of it should be used.

I’m nowhere near familiar enough with Tiled development and scripting to make this myself, but I think this is a fairly elegant solution to the remapping problem. One last feature I’d like to request for this is some way to remap many maps in one go, rather than being confined to doing this on just the active map.