Bring maps from Tiled and LDtk, and animated sprites from Aseprite and TexturePacker.
Tiled, LDtk, Aseprite & TexturePacker
Already built maps in Tiled or LDtk, or animated characters in Aseprite or TexturePacker? Import them instead of redrawing them. Maps become zones you can open in the Map editor; sprite sheets become sprite assets you can give to any character, mob, NPC or event.
Both importers live on the Import/Export page:
| Tab | What it imports |
|---|---|
| Tiled & LDtk | Tiled maps (.tmj, .tmx) with their tilesets (.tsj, .tsx), and LDtk projects (.ldtk, plus .ldtkl level files) → one zone per map or level |
| Aseprite & TexturePacker | A sprite-sheet .json export and its .png → one sprite asset with its animations |
They work the same in the Desktop Studio and the hosted editor. Your art goes straight into your project's media library, so large sheets are fine.
Import a Tiled or LDtk map#
- Open Import/Export → Tiled & LDtk.
- Click Choose files and select the map file, every tileset image it uses, and any external tileset (
.tsx/.tsj) or LDtk level (.ldtkl) files. Or click Choose folder… and pick the folder that holds them all — the importer matches files to the paths your map refers to. - Click 1. Analyze. You see the tilesets the map uses, a ✓ next to each image that was found, and — for LDtk — a checkbox per level. Untick levels you don't want.
- Click 2. Upload art & preview. The tileset images are uploaded to your media library (a copy already there is reused), and you get a preview of every zone: its size, how many tiles, blocked cells and events it will have, which zone layer each of your layers goes to, and anything that can't come across. Nothing is created yet.
- Click 3. Create zones. Each map or level becomes a new zone. Open it from the Map editor.
How your layers come across#
A zone has one floor, two object layers and two layers drawn above characters. Your layers fill them bottom to top:
| Your layer | Becomes |
|---|---|
| The lowest tile layer | Floor |
| The next ones | Object layer 1, then Object layer 2 |
| A layer named like Above, Roof, Overhead, Canopy, Tops or Foreground | An above-player layer (drawn over characters) |
| A layer named Collision, Solid, Blocking or Colliders | Not drawn — every painted cell blocks movement |
| A Tiled object layer / LDtk Entities layer | Events (one per object), see below |
To choose yourself in Tiled, give a layer a custom string property ed5Layer with one of floor, object1, object2, fringe, fringe2 or collision. A sixth drawn layer is merged into the layer below it — the preview tells you when that happens.
What else comes across#
| From | Becomes |
|---|---|
Tile shapes drawn in Tiled's collision editor, or a tile property solid / collides / blocked set to true | That tile blocks movement wherever it is painted |
| LDtk enum tags named Solid, Collision, Wall or Blocked on tileset tiles | Those tiles block movement |
| An LDtk IntGrid layer named Collision, or IntGrid values named wall / solid | Blocked cells |
| Tiled objects (points, rectangles, ellipses, polygons, text) and LDtk entities | Events on the object's top-left tile, named after the object. Its type/class, size and custom properties/fields are written in the event's note so you can wire it up |
| Tiled tile objects one cell in size | A placed object on Object layer 2 (or the layer its object layer's ed5Layer names) |
| Each tileset image | A tileset in your tile palette, plus an object definition for every tile you used on an object layer |
What is refused or simplified#
| Case | What happens |
|---|---|
| Staggered or hexagonal Tiled maps | Refused. Their rows are offset, which this engine's square grid can't represent. Recreate the map as orthogonal or isometric in Tiled |
| Isometric Tiled maps | Imported cell for cell, with tilesets marked isometric. They only look right while World Settings → View Mode is Isometric (orthogonal maps and LDtk want Top-down) — the preview warns you when yours doesn't match |
| Tilesets made of separate images (Tiled "image collection") | Refused — tiles from them are left empty. Pack the images into one sheet |
| Tilesets with margin or spacing | Re-cut into a tight grid automatically on upload |
| Flipped or rotated tiles | Imported unflipped |
| Animated tiles | Imported as their first frame |
| Image layers | Skipped — set the picture as the zone's parallax background instead |
| Hidden layers | Skipped (a hidden collision layer still blocks movement) |
| zstd-compressed Tiled layers | Refused — save with the CSV or base64 (zlib/gzip) layer format |
| Tile objects bigger than one cell | Not placed; their object definitions are created so you can place them by hand from the Objects palette |
| Areas and shapes | Become a single event on their top-left tile |
| Maps larger than 1024×1024 tiles | Refused — split the map |
| LDtk's built-in icon atlas | Refused — it isn't part of your project |
Gotchas#
- Every import makes new zones. Importing the same map twice gives you two zones; delete the old one when you re-import.
- Missing images — a tileset whose image you didn't choose imports as empty tiles, and the preview names the missing file. Choose it and preview again.
- Separate LDtk level files — if you saved levels to separate files, include the
.ldtklfiles (choosing the folder does this for you). - Big LDtk projects import eight levels at a time; the page runs the batches for you.
- Publish afterwards so a managed server picks up the new zones.
Import an Aseprite or TexturePacker sprite#
- In Aseprite use File → Export Sprite Sheet, tick JSON Data (Hash or Array) and Tags on the Output tab. In TexturePacker pick the JSON (Hash) or JSON (Array) data format.
- Open Import/Export → Aseprite & TexturePacker and choose the
.jsonand its.pngtogether. - Check the summary: frame size, the animations it found and how fast they play. Rename the sprite if you like.
- Click Create sprite. It appears under Assets → Sprites, and you can pick it in any character, mob, NPC or event sprite field, or open it in the sprite editor.
Fields#
| Field | What it does |
|---|---|
| Sprite name | The sprite asset's name. Defaults to the JSON file's name |
| Animations (Aseprite) | One per frame tag, named after the tag. Idle, Walk, Attack and the other built-in names drive gameplay; any other name is a custom animation |
| Tag direction | Forward loops, Reverse loops backwards, Ping-pong plays back and forth |
| Tag repeat of 1 | Plays once instead of looping |
| Frame duration | The tag's average frame time |
| Animations (TexturePacker) | Frames named walk_01, walk_02… become an animation called walk, in number order. If your export has an animations list, that is used instead |
Gotchas#
- Trimmed, rotated or padded sheets are fine. The importer lays the frames back out on an even grid before upload, keeping each frame's position so feet don't jump.
- No tags in Aseprite — every frame becomes one looping idle animation. Tag your animations and export with Tags ticked.
- Uneven frame timings — an animation plays at one speed; the importer uses the average and tells you.
- TexturePacker has no timing — every animation plays at 100 ms per frame. Change it in the sprite editor.
- Multipack TexturePacker exports (several sheets) are refused — export one sheet per file.
- Split Layers Aseprite exports don't line up with tags — export with layers merged.
- Importing the same sheet image again updates that sprite rather than making a copy.
For tools and AI assistants#
Both imports are ordinary Studio operations with a dry run. importExternalMap takes the map text, the side files and the media ids of already-uploaded tileset images, and with dryRun: true returns every zone it would create — size, layer assignments, tileset and object definitions, chunk and event counts, and each refused item with a code. importExternalSpriteSheet does the same for a sprite: its dry run reports the frame grid, the animations and, for trimmed or rotated sheets, the grid the frames are redrawn onto before upload.