Skip to content

Support Aseprite files (.ase/.aseprite) as Tiled tileset images #1363

@obiot

Description

@obiot

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions