i dont undestand how that would open?, like in pratice how do we use it simplyfy most of us arent familiar with such intricaces of aseprite
- Just specify for Tile map layer to use external .ase file as tileset
- Draw any content in that .ase file with frames = tiles concept in mind
- This content will automatically be flattened (to get rid of layers) to be used as tiles
- To edit external tiles you will have to edit that .ase file
- But Aseprite will auto-jump to new/old frame of that .ase file by opening that sprite in new tab at specific frame when you try to edit tiles at layer with external tileset
You may ask what if you want to see and edit all external tileset tiles at once — you should create separate working-on-tileset .ase with Tile map layer for this — and just switch between this working-on-tileset sprite (used to order tiles in different shapes) and tileset sprite itself (to edit tiles content).
so like a photoshop smart object? i think thats overcomplex. just saving a tileset in a specific archive type and importing in when creating a tileset layer would be way simpler in pratice and in programming i think
dunno @dacap what do you think which is easier to make
Simpler does not always mean better. Specific format will allow a lot less things to do. No easy Metatiles. No debug overlays. No tags-based debug info. No easy exporting. No easy layered tiles editing (very cool thing!). Extra efforts to code and support a whole new format.
While supporting .ase tilesets will require only a few thing to code: 1) new mode (external .ase tileset), 2) sync re-bake button and notification that sync required, 3) opening .ase tiles when an artist try to edit tile or create new tile. Almost nothing. The same internal tileset, but with function to re-bake tileset from source .ase file when it was changed and when you open sprite with such tileset used.
But surely at the end of the day, if you want to be that complex with it you could use a more complicated program like photoshop? Not sure if I’m alone here, but I’ve always perceived aseprite as a program that’s easy to use rather than being as in depth as industry-standard programs, so I personally prefer the simpler way of making a new file.
i agree, the thing i like in aseprite too, is that even the complex stuff can be easily done with a few examples like plugins, also its the way pyxel edit do it too, and he solenely focused on tiiles
But it’s simple. Draw tiles in separate .ase file. That’s all. Why be afraid of just using external .ase files?
thats clumsy i want to be able to save and open tilesets in the fly.
And you will be able to save and open tilesets in the fly. But why another format? Save to .ase (editor can generate new files), open from .ase (generated or create manually). Why do you need yet another format and extension for it? Also editor can create .ase tileset tileframes automatically and put content there, but only in case of simple one-layer .ase tiles.
This way or another you will have complications — when several your .ase projects using the same external tileset. Because when you modify this tileset (re-save it) it will affect all of your projects, even those that are not open now. And later when you open them you may find them broken. So another good option if you don’t want hard linking should be “Load tileset” instead of “Use external tileset”.
I wasn’t able to read the whole topic (this and Proposal — External tilesets using just .ase files), but about the file format for tilesets: we can easily use .aseprite format to store just tilesets, in the same way we use the .aseprite format to store only a palette (where a dummy a indexed canvas of 16 columns x required rows depending on the number of palette colors is automatically generated).
finally a good sumary
Good. The question is will you allow to edit these tilesets as regular sprites? WIll you allow to make multi-layer edits of these tiles and then still use them as tileset by flattening all visible layers?
Yes, we’ll allow to use flattened tilesets that are created from multi-layers. In that case the tileset will be “linked as an Import Sprite Sheet command” (or somthing similar). There are some steps:
- We have to improve the Import Sprite Sheet action to support more parameters (e.g. multiple grids? ignore empty cells? find tiles automatically?)
- Once the Import Sprite Sheet command is improved & we support linked .aseprite <-> files in some way (some work in progress), we’ll be able to specify a tileset from external files with Import Sprite Sheet parameters from the tileset dialog (this will enable a kind of metatiles).
As a final goal (maybe too ambitious, but I think it’s something required) would be to do an import/export/bi-directional tiles editing: So not only Import Sprite Sheet should work to import and external tileset, but we could edit pixels in the tileset and those changes should be reflected in the linked/external file (and those changes should be chained on other external tilesets).
A big problem about this: when multiple-layers are used for a tileset that is imported, how do we support editing those pixels? where are sent the changes to pixels? (a new layer? a target layer? should we show all tileset layers in the timeline in some way?)
Hmm. I think showing all tileset layers as sub-layers of Tilemap layer will be best here. But it should be optional and never spend any computation resources until expanded. And implementation will require a strict Import Sprite Sheet standard.
Also there will be problem with moved and removed tiles in external tileset and it should have some solution too. Like selecting tile or multiple tiles with (Tiles) Marquee tool and then executing “Remap Tiles To” command and pointing new base tile for remapped tiles.
Is there any way to export a tileset as a spritesheet PNG file?
Except manually placing every tile once on a canvas and exporting it instead.
Hi folks,
I wanted some functionality to arrange tile exports in columns so I modified @dacap’s gist above. Thought I’d share. I’ll leave the planning on what features the built-in implementation should have to others.
Dialog and test looks like this
Two sample results look like these:
3 column export beginning at index 1.
4 column export beginning at index 0.
(Notice the tiles are not properly ordered in the original.)
local defaults = {
filePath = "",
startIndex = 0,
count = 256,
columns = 8
}
local dlg = Dialog { title = "Export Tileset" }
dlg:file {
id = "filePath",
label = "Path:",
save = true,
focus = false,
filename = defaults.filePath
}
dlg:newrow { always = false }
dlg:slider {
id = "startIndex",
label = "Start:",
min = 0,
max = 255,
value = defaults.startIndex
}
dlg:newrow { always = false }
dlg:slider {
id = "count",
label = "Count:",
min = 1,
max = 256,
value = defaults.count
}
dlg:newrow { always = false }
dlg:slider {
id = "columns",
label = "Columns:",
min = 1,
max = 32,
value = defaults.columns
}
dlg:newrow { always = false }
dlg:button {
id = "confirm",
text = "&OK",
focus = false,
onclick = function()
-- Original export script:
-- https://gist.github.com/dacap/9df368ba276a45048dc85f96b23ea818
-- Discussion on tileset export functionality:
-- https://community.aseprite.org/t/saving-tilesets/9398/22
-- For determining undocumented object methods:
-- https://stackoverflow.com/questions/2620377/lua-reflection-get-list-of-functions-fields-on-an-object
local version = app.version
if version.major >= 1 and version.minor >= 3 and TilesetMode then
local sprite = app.activeSprite
if sprite then
local layer = app.activeLayer
if layer then
local isTileMap = layer.isTilemap
if isTileMap then
local tileSet = layer.tileset
-- for key, value in pairs(getmetatable(tileSet)) do
-- print(key, value)
-- end
local tileCount = #tileSet
local grid = tileSet.grid
local tileDim = grid.tileSize
local tileWidth = tileDim.width
local tileHeight = tileDim.height
local args = dlg.data
local filePath = args.filePath or defaults.filePath
local startIndex = args.startIndex or defaults.startIndex
local count = args.count or defaults.count
local columns = args.columns or defaults.columns
local si = math.min(tileCount - 1, math.max(0, startIndex))
local vc = math.min(tileCount - si, math.max(1, count))
local imgWidth = tileWidth * columns
local imgHeight = tileHeight * math.ceil(vc / columns)
-- Original script either copies or acquires a reference
-- to the image specification. Not sure if that makes a
-- difference to new image; ImageSpec also tracks the
-- transparentColor.
-- https://github.com/aseprite/api/blob/main/api/imagespec.md#imagespec
local image = Image(imgWidth, imgHeight, sprite.colorMode)
for i = 0, vc - 1, 1 do
local x = i % columns
local y = i // columns
local xScaled = x * tileWidth
local yScaled = y * tileHeight
local tile = tileSet:getTile(si + i)
image:drawImage(tile, xScaled, yScaled)
end
if #filePath > 0 then
image:saveAs(filePath)
dlg:close()
else
app.alert("Invalid file path (empty String).")
end
else
app.alert("The active layer is not a tilemap.")
end
else
app.alert("There is no active layer.")
end
else
app.alert("There is no active sprite.")
end
else
app.alert("Version 1.3 or later is required to use tilemaps.")
end
end
}
dlg:button {
id = "cancel",
text = "&CANCEL",
onclick = function()
dlg:close()
end
}
dlg:show { wait = false }
Probably there are edge cases that will catch this out.
Thanks! Best,
Jeremy
Hi @Ethan_Buttazzi, no progress so far but I have plans to take v1.3 development back next month. Meanwhile the best workaround is using a script like this: GitHub - dacap/export-aseprite-file: Little Aseprite script to export the data inside a .aseprite