A multi-platform container suite providing headless, curated asset-processing toolchains for 2D game development pipelines, build automations, and GitHub Actions CI workflows.
Built on Ubuntu 24.04 LTS (Noble Numbat) with native multi-architecture support for linux/amd64 (x86_64) and linux/arm64 (Apple Silicon / ARM64).
| Tool | Version | CLI Binary | Tier | Purpose | Upstream License |
|---|---|---|---|---|---|
| Tiled | 1.12.2 | tiled |
Free (gdtk) |
2D tilemap export (JSON, Lua, CSV) via headless Xvfb | GPL-2.0-or-later |
| tile-extruder | 2.1.1 | tile-extruder |
Free (gdtk) |
Extrudes tile borders to prevent texture bleeding & seams | MIT |
| yaml | 2.9.1 | yaml |
Free (gdtk) |
Fast YAML-to-JSON and JSON-to-YAML formatting & parsing | Apache-2.0 |
| Aseprite | v1.3.18.6 | aseprite, ase |
Non-Free (gdtk-non-free) |
Headless sprite slicing, tags export, and sheet packing | EULA (Proprietary) |
Important
- Public Registry Images (
ghcr.io/kidthales/gdtk): Contains exclusively open-source tools with permissive or copyleft distribution licenses (Tiled, tile-extruder, yaml) and is published Publicly on GitHub Container Registry. - Private / Local Non-Free Images (
gdtk-non-free): Aseprite is governed by the Aseprite EULA. While compiling Aseprite from source for personal or internal commercial studio use is fully permitted, redistributing compiled binaries to third parties is prohibited. Consequently,gdtk-non-freeimages hosted on GitHub Container Registry (ghcr.io/kidthales/gdtk-non-freeandghcr.io/kidthales/aseprite) are configured as Private packages. - Local Build for External Users: External developers can build
gdtk-non-freelocally in two simple steps using the instructions below. Compiling locally for personal use is 100% compliant with the Aseprite EULA.
Export a Tiled map to JSON with resolved custom types:
docker run --rm -v "${PWD}:/workspace" ghcr.io/kidthales/gdtk:latest \
tiled --export-map json --resolve-types-and-properties --embed-tilesets maps/level1.tmx maps/level1.jsonExtrude tileset margins by 1px to eliminate camera scrolling seams:
docker run --rm -v "${PWD}:/workspace" ghcr.io/kidthales/gdtk:latest \
tile-extruder --tileWidth 16 --tileHeight 16 --input tilesets/dungeon.png --output tilesets/dungeon_extruded.pngConvert a YAML game manifest to formatted JSON:
docker run --rm -v "${PWD}:/workspace" ghcr.io/kidthales/gdtk:latest \
bash -c "cat config.yml | yaml --json --indent 2 --single > config.json"Batch-export sprite frames and slices using local gdtk-non-free:
docker run --rm -v "${PWD}:/workspace" gdtk-non-free:latest \
aseprite --batch sprites/player.aseprite --sheet output/player.png --data output/player.jsonYou can plug ghcr.io/kidthales/gdtk directly into your game repository's Taskfile.yml to automatically recompile maps and tilesets only when source files change:
version: '3'
tasks:
export:maps:
desc: Export Tiled TMX maps to JSON using GDTK
sources:
- 'raw-assets/maps/*.tmx'
- 'raw-assets/tilesets/*.tsx'
generates:
- 'game/assets/maps/*.json'
cmds:
- docker run --rm -v "{{.ROOT_DIR}}:/workspace" ghcr.io/kidthales/gdtk:latest
tiled --export-map json --resolve-types-and-properties raw-assets/maps/level1.tmx game/assets/maps/level1.json
extrude:tilesets:
desc: Extrude tileset borders to prevent rendering seams
sources:
- 'raw-assets/tilesets/*.png'
generates:
- 'game/assets/tilesets/*_extruded.png'
cmds:
- docker run --rm -v "{{.ROOT_DIR}}:/workspace" ghcr.io/kidthales/gdtk:latest
tile-extruder --tileWidth 16 --tileHeight 16 --input raw-assets/tilesets/terrain.png --output game/assets/tilesets/terrain_extruded.pngRun headless asset validation or automated map exports directly inside a containerized GitHub Actions job:
name: Compile Game Assets
on:
push:
branches: [main]
jobs:
build-assets:
runs-on: ubuntu-latest
container:
image: ghcr.io/kidthales/gdtk:latest
steps:
- uses: actions/checkout@v7
- name: Export Tiled Maps
run: |
tiled --export-map json raw-assets/maps/dungeon.tmx game/assets/maps/dungeon.json
- name: Extrude Tilesets
run: |
tile-extruder --tileWidth 16 --tileHeight 16 --input raw-assets/tilesets/dungeon.png --output game/assets/tilesets/dungeon_extruded.pngThis repository uses go-task for cross-platform local automation across Windows, macOS, and Linux:
# Display available tasks
task
# Build free toolkit image (gdtk:latest)
task build
# Build non-free image with Aseprite (gdtk-non-free:latest)
task build -- gdtk-non-free
# Run smoke tests against local images
task test
# Run static analysis suite (BuildKit check, Hadolint, Actionlint, EditorConfig)
task lint
# Print resolved bake configuration
task printYou can customize build variables by creating a .env file in the root directory:
IMAGES_PREFIX="kidthales/"
IMAGES_TAG="2026.10.0"
ASEPRITE_GIT_REF="v1.3.18.6"
PLATFORMS=["linux/amd64", "linux/arm64"]Warning
Values assigned in .env must be wrapped in double quotes. This is a syntax requirement of the underlying docker buildx bake -f .env invocation.
To build the non-free image locally without downloading private images from GHCR:
- Clone and compile the headless Aseprite base:
git clone https://github.com/kidthales/docker-aseprite-headless.git cd docker-aseprite-headless task build - Build
gdtk-non-freein this repository:cd ../docker-game-development-toolkit task build -- gdtk-non-free