Context
Since Tiled 1.11, users can reference .ase / .aseprite files directly as tileset images (via the qaseprite Qt plugin). When a Tiled project uses this feature, the TMX/TSX tileset image attribute points to an .aseprite file instead of a .png.
melonJS already added support for Tiled up to version 1.12 but missed this Aseprite integration. Currently, if a tileset references an .aseprite image, the loader fails because preloadImage() tries to load it as a standard image format via createImageBitmap(), which doesn't understand the Aseprite binary format.
What we already have
melonJS has a complete Aseprite JSON parser at src/video/texture/parser/aseprite.js that:
- Parses frame definitions (position, size, trim, rotation)
- Extracts animation sequences from
frameTags
- Supports pivot points for anchor calculation
- Is used by
TextureAtlas when meta.app includes "aseprite"
The current Aseprite workflow requires two pre-exported files: a .json (metadata) and a .png (spritesheet). The goal is to also support the raw .aseprite binary format so Tiled maps that reference .aseprite files "just work".
Proposed implementation
1. Aseprite binary parser (src/loader/parsers/aseprite.js)
Create a parser for the Aseprite file format spec:
- Parse the binary
.ase/.aseprite file header (magic number 0xA5E0, frame count, dimensions, color depth)
- Extract the spritesheet image by compositing visible layer cels per frame into a strip/grid PNG
- Extract frame metadata (position, duration) and tags (animation sequences) into the same JSON structure that
parser/aseprite.js already understands
- Return both the composited image and the parsed JSON metadata
This is the most complex part. Consider using an existing MIT-licensed library like AsepriteParser as a reference, or port the relevant parts of the Aseprite file I/O code.
2. Register the parser in the loader
// in loader.js initParsers()
setParser("aseprite", preloadAseprite);
The parser should:
- Fetch the file as
arrayBuffer
- Parse the binary data into image + JSON metadata
- Store the composited image in
imgList and the metadata in jsonList (or a new asepriteList)
- This allows
TextureAtlas to pick it up via the existing getJSON() + getImage() pattern
3. Update TMXTileset to handle .aseprite references
In TMXTileset.js, when the tileset image attribute ends in .ase or .aseprite:
- Instead of calling
getImage(tileset.image) directly (which expects a pre-loaded PNG), detect the extension and:
- Load the
.aseprite file via the new parser
- Use the composited spritesheet image as the tileset texture
- Optionally expose frame/animation data for animated tilesets
4. Update the image loader to recognize .aseprite extensions
In preloadImage() (src/loader/parsers/image.js), add .ase/.aseprite to the extension check alongside .dds, .pvr, etc.:
if (ext === ".ase" || ext === ".aseprite") {
// redirect to the Aseprite binary parser instead of createImageBitmap
return preloadAseprite(data, onload, onerror, settings);
}
5. Reuse the existing Aseprite JSON parser
The existing src/video/texture/parser/aseprite.js should be reusable as-is — the binary parser (step 1) just needs to produce the same JSON structure that this parser expects. No changes needed to the texture atlas pipeline.
6. Add a Tiled map example with Aseprite tileset
Add a test map to the Tiled Map Loader example (packages/examples/src/examples/tiledMapLoader/) that uses an .aseprite file as a tileset image. This validates the full pipeline:
- TMX map referencing a tileset with
<image source="tileset.aseprite" .../>
- The loader auto-detects the
.aseprite extension and uses the binary parser
- The tileset renders correctly with animation support
Complexity estimate
- Binary parser: Medium-high — the Aseprite format has frames, layers, cels, color palettes, and multiple blend modes. For tileset use, we primarily need the composited flat image + frame timing.
- Loader integration: Low — follows the existing
preloadOBJ/preloadMTL pattern
- TMXTileset update: Low — extension check + redirect to the new parser
- Example map: Low — create a small Tiled map with an Aseprite tileset
- Alternative: Instead of a full binary parser, we could require users to export
.png + .json alongside the .aseprite file and auto-detect the companion files. Simpler but less seamless.
References
Context
Since Tiled 1.11, users can reference
.ase/.asepritefiles directly as tileset images (via the qaseprite Qt plugin). When a Tiled project uses this feature, the TMX/TSX tilesetimageattribute points to an.asepritefile instead of a.png.melonJS already added support for Tiled up to version 1.12 but missed this Aseprite integration. Currently, if a tileset references an
.asepriteimage, the loader fails becausepreloadImage()tries to load it as a standard image format viacreateImageBitmap(), which doesn't understand the Aseprite binary format.What we already have
melonJS has a complete Aseprite JSON parser at
src/video/texture/parser/aseprite.jsthat:frameTagsTextureAtlaswhenmeta.appincludes "aseprite"The current Aseprite workflow requires two pre-exported files: a
.json(metadata) and a.png(spritesheet). The goal is to also support the raw.asepritebinary format so Tiled maps that reference.asepritefiles "just work".Proposed implementation
1. Aseprite binary parser (
src/loader/parsers/aseprite.js)Create a parser for the Aseprite file format spec:
.ase/.asepritefile header (magic number0xA5E0, frame count, dimensions, color depth)parser/aseprite.jsalready understandsThis is the most complex part. Consider using an existing MIT-licensed library like AsepriteParser as a reference, or port the relevant parts of the Aseprite file I/O code.
2. Register the parser in the loader
The parser should:
arrayBufferimgListand the metadata injsonList(or a newasepriteList)TextureAtlasto pick it up via the existinggetJSON()+getImage()pattern3. Update TMXTileset to handle
.asepritereferencesIn
TMXTileset.js, when the tilesetimageattribute ends in.aseor.aseprite:getImage(tileset.image)directly (which expects a pre-loaded PNG), detect the extension and:.asepritefile via the new parser4. Update the image loader to recognize
.asepriteextensionsIn
preloadImage()(src/loader/parsers/image.js), add.ase/.asepriteto the extension check alongside.dds,.pvr, etc.:5. Reuse the existing Aseprite JSON parser
The existing
src/video/texture/parser/aseprite.jsshould be reusable as-is — the binary parser (step 1) just needs to produce the same JSON structure that this parser expects. No changes needed to the texture atlas pipeline.6. Add a Tiled map example with Aseprite tileset
Add a test map to the Tiled Map Loader example (
packages/examples/src/examples/tiledMapLoader/) that uses an.asepritefile as a tileset image. This validates the full pipeline:<image source="tileset.aseprite" .../>.asepriteextension and uses the binary parserComplexity estimate
preloadOBJ/preloadMTLpattern.png+.jsonalongside the.asepritefile and auto-detect the companion files. Simpler but less seamless.References
src/video/texture/parser/aseprite.jspackages/examples/src/examples/aseprite/