Game release setup, packaging and publishing¶
For native payload rules and detailed package verification, read native release packages. This guide owns shared Editor/CLI setup, browser releases and explicit uploads.
Open an existing ludus.project.json in the Ludus Editor. Release actions require
an idle workspace and a clean, saved version-2 CMake project.
Use Release > Set Up Releases to select Linux native, macOS app or Emscripten browser
packaging and an optional itch.io username/game. Setup adds game-owned
ludus.release.json, explicit cmake/GameRelease.cmake install rules, notices,
release instructions and a GitHub workflow. It appends one CMake include and
preserves application source, descriptor and engine lock. It refuses existing
release files or notices instead of replacing authored content. Review the files
and complete asset/dependency licenses before committing.
An empty itch.io destination leaves it configurable through the GitHub repository
variable ITCH_IO_TARGET. A project may provide scripts/release-prepare to
prepare CI build inputs; setup records that script as an argv array, without a
shell. Browser projects must provide a web-emscripten-release preset, a matching
Release browser SDK and an executable with OUTPUT_NAME index producing
index.js and index.wasm. Generated install rules also require index.html.
Other filenames/extra workers need explicitly authored install rules.
Use Release > Package Release with linux-release, macos-release or web-release, a version
and an optional Release SDK prefix. The Editor uses the shared installed backend
through its asynchronous tooling adapter. Configure, build, install and macOS signing retain
owned process groups, bounded output, cancellation and parent-loss cleanup.
The verified package directory and SHA256 appear in Output. Packaging never uploads.
The equivalent CLI commands are:
ludus project release init MyGame --platform web --tools-ref <immutable-Ludus-commit> --itch-target username/game
ludus project package MyGame --profile web-release --version 0.1.0
ludus project package verify <package-directory>
ludus project publish plan MyGame --package <package-directory> --destination web --allow-local-inputs
Native policies are documented in the native release guide. Browser verification checks archive paths, hashes/modes, root HTML and local HTML asset references, required JavaScript/WebAssembly, Wasm header/section bounds and absence of debug custom sections/native binaries, plus notices/licenses. Installation must match the selected CMake executable's current JavaScript and WebAssembly. Verification does not execute game code or prove all dynamically constructed JavaScript URLs resolve; playtesting the extracted and hosted game remains a separate acceptance step.
Browser SDKs currently use the project's explicit CMake preset, rather than the native SDK catalog resolver. Their actual SDK manifest identity is recorded, and these packages are classified as local inputs. CI upload opts into those inputs explicitly after a separate build job and exact artifact digest check.
macOS creates a local ad-hoc signed app and a package-only GitHub workflow.
Set LUDUS_RELEASE_SDK_URL and LUDUS_RELEASE_SDK_SHA256 for a matching thin
Release SDK. It has no upload step or account secret. Live upload transport,
Developer ID signing and notarization remain separate; see the
macOS package contract.
Automatic GitHub uploads (Linux and browser)¶
The generated workflow runs for v* tags and manual dispatch. Actions and the
Ludus tooling source are pinned to immutable commits. It builds and verifies the
package in one job, transfers it using GitHub artifacts, verifies again in another
job, and uploads through the explicit ludus project publish upload command.
Repository releases are serialized without cancelling an active upload. PR events
never trigger this workflow; fork code receives no upload credential.
Configure these settings in the game repository:
- An
itch-releaseGitHub environment with secretBUTLER_API_KEY. - Repository variable
ITCH_IO_TARGETif no destination was saved into the config. - For native CI:
LUDUS_RELEASE_SDK_URLandLUDUS_RELEASE_SDK_SHA256, identifying a matching Release SDK archive: a public HTTPS URL, or a release asset of the game repository itself, which the job fetches with its read-only token (see project CI). Project-specific shader tools and assets should be prepared byscripts/release-prepare.
The secret is scoped to the upload step only. Tool installation, project bootstrap,
CMake, package verification and compiler subprocesses receive no upload secret.
The uploader copies the archive and sidecars into a private directory, verifies
the snapshot and approved digest, downloads official butler 15.31.0 using pinned
archive/executable SHA256s, and calls butler push with an argv array. It uses an
isolated credential home, streams redacted bounded diagnostics and makes one
attempt. Success produces an upload-submitted receipt under out/publish-receipts;
it does not claim processing or hosted gameplay was verified. Failures do not
retry automatically. Receipt files contain no credentials and leave packages unchanged.
For a browser game, create its itch.io page and select the HTML game type. After the first push, mark the uploaded channel playable in browser in Edit game. Butler cannot configure that page setting. See the official push documentation, CI authentication documentation, and installation documentation.