I just want to make sure I’m not missing something before I go and open an issue on GitHub. I can’t find a way to add a tileset to a map by reference rather than embedding it.
The API to add tilesets:
map.addTileset(tileset)
results in embedding the tileset in the map, even if that tileset was literally just loaded from disk via the tileset format’s read method.
Even if I skip the addTileset call and just place tiles from that tileset on the map, it’s implicitly added as an embedded tileset.
Am I missing something? Or is there really no way to do this in the API?
There’s no issue with TileMap.addTileset(), the problem is that you’re using TilesetFormat.read(), which creates a wholly new Tileset with no connection to the source file, which is what causes it to get embedded. To keep a connection to the file so that the TileMap maintains an external Tileset reference, you need to use tiled.open().
Using tiled.open() can be a problem in situations such as running Tiled via CLI or wanting to avoid opening the Tileset as a document tab. There’s already an issue and a WIP PR open to remedy that with a tiled.load() method that works similarly to tiled.open() but without opening a document tab: Scripting: Set fileName when using TilesetFormat.read() or MapFormat.read() · Issue #3517 · mapeditor/tiled · GitHub
1 Like
So, if the flow is to create a tileset, save it to disk, and then add it to a map, does that mean I need to reload the tileset I just saved using tiled.open in order to avoid embedding it? This works, but feels wrong and ugly. (Also, the fact that a tab is opened is definitely a tad annoying. And if the tileset loaded by TilesetFormat.read is seen as a new copy, it’s definitely a bit weird for it to be read-only.)
If you saved the tileset with tiled.save, then you shouldn’t need to open it. If you “saved” it with TilesetFormat.write(), then yes, you would need to open it, because write doesn’t save. Basically, Tilesets that aren’t document tabs aren’t documents, and therefore don’t have document-specific data like what file(s) they’re connected to. Once you’ve got a document, then you can do things like save it and have external references to it.
The issue I linked explains why the weirdness is as it is. tiled.load() won’t address the fundamental weirdness, but will at least provide a way for scripts to work with Tilesets that’s cleaner than open.
I guess by tiled.save() you mean tileset.save()? So that works even if it was created as a new Tileset()?
Sorry, had tiled.open on the brain. You can save() an asset created with new, but only if it’s open as a document tab, e.g. by assigning it to tiled.activeAsset, and I’m not even sure that’s possible with a Tileset (it is possible with TileMaps). So fully automating embedding a new Tileset as an external tileset is only possible if you write() and then open() (or load(), when that becomes available).
@bjorn A better way to fully automate saving a newly created Asset as a document would be nice, given the fact that this is required for external Tileset references, which are normally encouraged over embedding. CelticMinstrel is far from the first person to be tripped up by this.
write() followed by the forth-coming load() would be transparent from the user’s POV, but still necessitates a redundant file read and looks hacky.
While most GUI Tiled scripts don’t generally need to create new Tilesets and embed them as external tilesets in a single action and open or load would be sensible since the creation and the embedding are in different contexts, in scripts meant for CLI, it is probably a much more common need to create Tilesets and create external references to them in one go.
If something like Asset.saveAs(path) isn’t possible, maybe an approach akin to Tile.setImage(image, sourcePath?) (i.e. TileMap.addTileset(tileset, sourcePath?) could work, so Tiled pretends the Tileset is coming from a given filename even if the Asset came from elsewhere. I imagine Asset.saveAs(path) would be easier to implement though.
1 Like