How to create unique tile ID's

Ah, it seems you are correct. The reason for this is that the CSV plugin was designed with a single tileset in mind and is not meant for maps with multiple tilesets. Normally, the tile IDs Tiled outputs are unique, as they include an offset that is unique to each tileset, allowing you to identify the tileset each tile belongs to. You would need extra metadata to tell you which tileset is which, though, as the tileset order is not guaranteed within Tiled. TMX files contain this data, the CSV output does not.

Here’s a script I wrote that lets you export CSV with global IDs. It adds a “CSV with GIDs” option in your export formats. Note that since these are TMX-style GIDs, 0 now means “no tile”, and the actual tile IDs start at 1. To help identify the tilesets used, it also outputs a MapName_tilesets.csv file, which lists firstgid, "tileset location" pairs, one per row, in increasing order of firstgid. To match the tiles to their tileset, check their ID against this list, their tileset will be the one with the largest firstgid that’s less than or equal to the tile’s global ID. It also numbers the outputted layer CSVs so that you know the layer order in addition to the layer names.
Caveat: It does not currently support grouped layers, because Tiled’s scripting API does not yet have a convenient way to access them. If you need group support, let me know and I can add it (it can be done, it’s just tedious work I’d rather avoid if it’s not needed).

var customMapFormat = {
    name = "CSV with GIDs",
    extension = "csv",
    
    write: function(map, fileName) {
		//Assign firstgids to each tileset:
		var firstgids = [];
		var tilesets = map.tilesets;
		firstgids[0] = 1;
		for(var i = 1; i < tilesets.length; i++) {
			firstgids[i] = firstgids[i-1] + tilesets[i-1].tileCount;
		}
		
		var prefix = fileName.search(".csv");
		if(prefix >= 0) prefix = fileName.substr(0, prefix);
		else prefix = fileName;
		var numLayers = 0;
		for (var i = 0; i < map.layerCount; ++i) {
            var curLayer = map.layerAt(i);
            if (curLayer.isTileLayer) {
				var file = new TextFile(prefix+"_"+numLayers+"_"+curLayer.name+".csv", TextFile.WriteOnly);
				var output;
                for (y = 0; y < curLayer.height; ++y) {
                    output = "";
                    for (x = 0; x < curLayer.width; ++x) {
						if(x > 0) output += ",";

						var cell = curLayer.cellAt(x, y);
						var tile = cell.tileId;

						var tileset = curLayer.tileAt(x, y);
						if(tileset) {
							tileset = tileset.tileset;
							//add the firstgid for this tile's tileset:
							tileset = tilesets.indexOf(tileset);
							if(tileset >= 0)
								tile += firstgids[tileset];

							if(cell.flippedHorizontally) tile = tile | 0x80000000;
							if(cell.flippedVertically) tile = tile | 0x40000000;
							if(cell.flippedAntiDiagonally) tile = tile | 0x20000000;
							if(cell.rotatedHexagonal120) tile = tile | 0x10000000;
						} else tile = 0;
                        output += tile;
					}
					file.writeLine(output);
                }
				file.commit();
				numLayers++;
            }
        }
		//Output a metadata file with what each tileset is:
		var file = new TextFile(prefix+"_tilesets.csv", TextFile.WriteOnly);
		var output = '';
		for(i = 0; i < tilesets.length; i++) {
			output += firstgids[i] + ', "' + tilesets[i].fileName + '"\n';
		}
		file.writeLine(output);
		file.commit();
	}
}

tiled.registerMapFormat("CSV with GIDs", customMapFormat);
1 Like