LÖVE (Love2D) is a lightweight framework for 2D games in Lua. Good for prototypes and small to medium games.
Website: https://love2d.org
A LÖVE game ships as a .love archive. The web build is that same archive bundled with love.js.
| Variable | Description | Default |
|---|---|---|
PROJECT |
Name used in output filenames | love2ddemo |
BIN_DIR |
Build-time checks | bin |
DIST_DIR |
Packaged artifacts | dist |
WEB_DIR |
Web files | dist/web |
LOVE_NAME |
Generated .love file | love2ddemo.love |
VERSION_FILE |
Version file for CI | .version |
make build # luac syntax check on every .lua file
make love # pack into dist/love2ddemo.love (skips .git, Makefile, dist/)
make web # download love.js, assemble dist/web/, patch index.html + player.js
make export VERSION=1.0.0 # both, zipped as love2ddemo-1.0.0.love.zip and -1.0.0.html.zip
make watch # rebuild on .lua change (needs fswatch)
make clean # remove bin/ and dist/
Copy example-tasks.json to .vscode/tasks.json as is. Tasks: Run Löve (default, Cmd+Shift+B), Build & Run Löve, Build .love package, Make build.
| File | Description |
|---|---|
dist/love2ddemo.love |
LÖVE package |
love2ddemo-<version>.love.zip |
Zipped .love |
love2ddemo-<version>.html.zip |
Web build |
love2ddemo-<version>.metadata.json |
Metadata for distribution |
love2ddemo-<version>-win-x64.zip |
Fused Windows build (exe + dlls) |
love2ddemo-<version>-mac-universal.zip |
Fused universal .app |
love2ddemo-<version>-linux-x64.zip |
Fused AppImage |
Local only: make, luac, zip, unzip, curl, sed, and fswatch for watch mode. CI images bring their own tools.
The pipeline is not in the game repo. Woodpecker asks the update server, and WarpEngine serves the whole config from /build/config (template lib/warp_engine/ci_templates/love.yaml.erb).
The repo needs three things:
# .woodpecker.yaml
platform: love
name: love2ddemo # only when the software name differs from the repo name
metadata.jsonapplication_token Woodpecker secret: a WarpEngine ApplicationToken with update + upload scopesBuilder images come from the update server's ci_platforms config. Preview the served pipeline:
curl "https://teletypegames.org/build/config?platform=love"
| Step | What it does |
|---|---|
| 1. version | read the version from metadata.json, else the git short hash; outside main/master prefix it as dev-<version>-<branch>; write .version |
| 2. build | in the love-builder image: pack the .love, build the love.js web bundle, patch the player and HTML with name + version, zip both |
| 3. binaries | fuse the .love into the official LÖVE release artifacts |
| 4. upload | copy metadata.json to love2ddemo-<version>.metadata.json, then POST /build/upload per file with the X-Update-Secret header |
| 5. publish | POST /build/publish with name, platform, version |
Fusing, per platform:
love.exe + .love concatenated, dlls included.love inside the official universal love.app, Info.plist patched to the project namemksquashfs. The AppImage runtime is glibc-linked, so it is never executed on the alpine builder; the squashfs offset comes from readelf.The LÖVE dist files come from the image cache at /opt/love-dist/, with a curl fallback to GitHub.
curl -X POST -H "X-Update-Secret: <SECRET>" \
"https://teletypegames.org/build/publish?name=love2ddemo&platform=love&version=1.0.0"
A .love package, a web bundle and three fused desktop builds, all versioned, uploaded and published. The public game index updates itself.