EN /HU | Login

TIC-80

TIC-80 is a tiny fantasy computer for small games. Code, sprites, maps, sound and music are all edited inside it.

Website: https://tic80.com Tools repository: https://git.teletypegames.org/build/tic80-tools


Makefile

A cartridge is one .lua file. To keep the code modular, we split it into many files and concatenate them at build time.

TEXT
project-root/
├── inc/
│   ├── core.lua
│   ├── player.lua
│   └── world.lua
├── impostor.inc      # build order, one file name per line
├── Makefile
└── README.md

impostor.lua is generated. Order matters: a file must come after the globals it uses.

Targets

SH
make build                  # concatenate inc/ files into <project>.lua
make minify                 # shrink the code, backup to <project>.original.lua
make export VERSION=1.0.0    # build + minify, then save .tic and .html.zip
make export_assets          # PALETTE/TILES/SPRITES/MAP/SFX/WAVES -> inc/meta/meta.assets.lua
make import_assets          # import assets/<type>/*.png into the cartridge
make watch                  # rebuild on change in inc/, the .inc file and assets/
make lint                   # luacheck, with line numbers mapped back to source files
make docs                   # ldoc HTML into docs/
make install_precommit_hook # .git/hooks/pre-commit runs make lint
make clean                  # remove generated files

export also copies the versioned files to unversioned names (impostor.tic, impostor.html.zip). export_assets keeps the graphics in version control as source code.

VS Code

Copy example-tasks.json from the tools repo to .vscode/tasks.json and replace impostor.lua with your cart name. Tasks: Run TIC80 (default, Cmd+Shift+B), Build & Run TIC80, Export assets, Make build.

Generated artifacts

File Description
<project>.lua Merged (and minified) source
<project>.original.lua Pre-minification backup
<project>.tic Cartridge
<project>.html.zip HTML build
<project>-*-docs.zip Documentation
<project>-*-win-x64.zip Windows player, cart baked in
<project>-*-linux-x64.zip Linux player, cart baked in
<project>-*-mac-x64.zip macOS (Intel) player, cart baked in

Requirements

Local only: make, tic80 in PATH, lua, luacheck, ldoc, curl, and fswatch for watch mode. CI installs its own tools.


Pipeline

The pipeline is not in the game repo. Woodpecker asks the update server for it, and WarpEngine serves the whole config from /build/config (template lib/warp_engine/ci/woodpecker/platforms/tic80/pipeline.yaml.erb).

The repo needs three things:

YAML
# .woodpecker.yaml
platform: tic80
  • name: <software> — only when the software name differs from the repo name
  • the application_token Woodpecker secret: a WarpEngine ApplicationToken with update + upload scopes, created in the admin

TIC-80 projects have no metadata.json. The version and the catalog metadata come from the comment header in inc/meta/meta.header.lua.

See the exact commands:

SH
curl "https://teletypegames.org/build/config?platform=tic80"

Steps

Step What it does
1. version the engine's shared step (since WarpEngine 1.7): the version from the -- version: line of inc/meta/meta.header.lua; on a tag a version tag has to match it; outside the repo's default branch and on a dev-<branch> tag dev-<version>-<branch>, with no version dev-<commit>; write .version
2. lint luacheck in the tools image (ci-tools on teletypegames.org, luacheck and ldoc preinstalled; without one, alpine + luarocks install on every run); merge inc/ in .inc order with a line map; fail on any issue
3. minify concatenate and minify with lua-minify-tic80; keep the original for docs
4. docs ldoc on the pre-minification source, zipped as <name>-<version>-docs.zip
5. export in the tic80pro image: save the .tic cart and export .html.zip
6. binaries export win / linux / mac with the cart baked in, one zip per slug; templates are downloaded from tic80.com, so this step needs network
7. upload on the tag only: POST /build/upload per file, X-Update-Secret header from application_token
8. publish on the tag only: POST /build/publish?platform=tic80
9. tag the engine's shared step (since WarpEngine 1.9), after a push only: a new version in the source gets its v<version> tag, whose pipeline runs the steps marked on the tag only; a version tagged already releases nothing; a dev build moves the branch's dev-<branch> tag onto the commit, so the newest dev build is published. See Versions and releases on the WarpEngine page

Raising the version is the release: a push builds and tags, and the tag's pipeline uploads and publishes (WarpEngine 1.9). A push that leaves the version as it is only builds.

The builder image (tic80pro) and the tools image come from the update server's ci_platforms config, not from the repo. With ci-tools the lint step went from 10–15 s to 3 s and the docs step from 12–14 s to 1 s.

Result

Linted, minified, versioned build; docs and native players attached as ReleaseAssets; the public game index updates itself. All build logic lives server-side — the repo carries only the marker and its token.


Builder image

TIC-80 Pro is a commercial product, sold on itch.io. The source is open, so with a license you can build your own Pro binary in a clean image.

DOCKERFILE
FROM ubuntu:24.04

RUN apt-get update && apt-get install -y \
      build-essential cmake git \
      libsdl2-dev libpipewire-0.3-dev libwayland-dev \
      ruby-dev lua5.4 libcurl4-openssl-dev \
    && rm -rf /var/lib/apt/lists/*

RUN git clone --recursive https://github.com/nesbox/TIC-80 /opt/TIC-80
RUN cd /opt/TIC-80/build \
    && cmake -DBUILD_PRO=On -DBUILD_SDLGPU=On -DBUILD_WITH_ALL=On -DBUILD_STATIC=On .. \
    && cmake --build . --parallel

ENV PATH="/opt/TIC-80/build/bin:${PATH}"
WORKDIR /workspace
CMD ["/bin/bash"]
Flag Why
BUILD_PRO=On enables the Pro features
BUILD_SDLGPU=On, BUILD_WITH_ALL=On GPU support and every optional feature
BUILD_STATIC=On one portable binary, no shared library surprises