A finished map exports three ways: a still image, an animation, or engine-ready game
data. In every case, wire the canvas output of tile_studio (plus the palette)
into the export node.
Still image — tile_canvas_render
Renders the map at a chosen time_ms as a regular Image. Feed it through any image
nodes (outline, gradient_map, …) and save with batch_export. This is the path
for using a map as the base of a single-piece artwork.
Animation — tile_canvas_animation_render
Given duration_ms and fps, outputs animated frames (frames: List) and a
sprite sheet (spritesheet).
frames→batch_export(name_{index}pattern) for a PNG sequenceframes→ GIF/APNG-style output nodes for movie formatsmax_framescaps the frame count (a warning is emitted when hit)
Engine bundles — tile_bundle_export
Connect canvas and tile_palette, choose an output folder and a profile.
Writing is staged → verified → atomically swapped; failures never leave a
half-written folder. Details are reported on the report output.
| Profile | Contents | Target |
|---|---|---|
| Image sequence (images_v1) | frames/frame_0000.png… + manifest |
Generic (video editing, custom processing) |
| Native (pixpipeline_native_v1) | atlas PNG + tileset.json + maps/map_0.json + manifest | Custom engines. The precise contract (coordinates, animation phase, collisions) is docs/contracts/tile-runtime-v1/ |
| Tiled (tiled_v1) | map.tmj + tileset.tsj + atlas.png | Tiled, and Unity/Godot via their Tiled importers |
Notes:
- Native bundle maps are rule-resolved — consumers don't implement any rule engine. Collision and metadata layers are included in the JSON
- Features Tiled cannot express (e.g. rasters that don't match the cell size) are reported as errors instead of being silently transformed
- The single-file compat exports
tiled_map_export/tiled_tileset_exportremain available
Headless (CLI) batch export
When running tile save/export nodes from the CLI, grant write access explicitly in the job file (Safe Open protection):
{
"project": "tile_studio_demo.ppl",
"readRoots": ["."],
"writeRoots": ["."],
"overrides": [
{ "nodeId": "25", "paramId": "save_mode", "value": "Overwrite" }
]
}
A complete working example ships as docs/ai/samples/tile_studio_demo.ppl +
tile_studio_demo.job.json (in distributions: ai/samples/). See
12 AI integration and the headless runner guide for details.