Package a C# game for Linux, Windows and macOS with onegame export: NativeAOT where the host allows it, a folder and an archive per target, and a JSON report of every file to check in CI.
Desktop exports work for a game made from the NuGet packages, with no engine checkout. An export is always the Release build without the development tools: no live control, no scenario runner, no capture or replay options.
Linux
onegame export --target linuxexported orchard 1.0.0 for linux-x64 (nativeaot): 5 files, 7408 KiB folder: /tmp/games/orchard/export/orchard-1.0.0-linux-x64 archive: /tmp/games/orchard/export/orchard-1.0.0-linux-x64.tar.gz (3583 KiB) warning glibc_too_new: Orchard needs glibc 2.38, newer than 2.31 in Steam's Linux runtime (and so on the Steam Deck). Build on an older system, or inside the Steam Linux Runtime SDK: see docs/exporting.md.
orchard-1.0.0-linux-x64/ Orchard the NativeAOT program run.sh starts the program from its own folder, from any current directory THIRD-PARTY-NOTICES.txt always fonts/ the game's fonts and their licences
The program gives the same state hash as the Debug build:
export/orchard-1.0.0-linux-x64/run.sh --headless --frames 60 --json{"ok":true,"game":"orchard","headless":true,"frames":60,"tick":60,"hash":"3245c24a6e2d4459","width":1280,"height":720}The archive is a .tar.gz with one top folder, sorted entries and a fixed timestamp, so the same folder gives the same archive. The glibc_too_new warning only matters for Steam: see Ship a game for Steam and the Steam Deck.
Windows and macOS from a Linux host
NativeAOT links with the target system’s toolchain, so from Linux the Windows and macOS exports are self-contained, trimmed CoreCLR builds, and the export says so:
onegame export --target winexported orchard 1.0.0 for win-x64 (coreclr-self-contained): 58 files, 25276 KiB folder: /tmp/games/orchard/export/orchard-1.0.0-win-x64 archive: /tmp/games/orchard/export/orchard-1.0.0-win-x64.zip (11733 KiB) skipped TestResults/: not a content folder (shipped folders: fonts, art, data) warning not_native_aot: NativeAOT for win-x64 needs a Windows host; this is a self-contained, trimmed CoreCLR build. Run the same command on a matching host for the NativeAOT build.
onegame export --target osxexported orchard 1.0.0 for osx-arm64 (coreclr-self-contained): 60 files, 26841 KiB folder: /tmp/games/orchard/export/orchard-1.0.0-osx-arm64 archive: /tmp/games/orchard/export/orchard-1.0.0-osx-arm64.tar.gz (10948 KiB) skipped TestResults/: not a content folder (shipped folders: fonts, art, data) warning not_native_aot: NativeAOT for osx-arm64 needs a Mac with Apple silicon host; this is a self-contained, trimmed CoreCLR build. Run the same command on a matching host for the NativeAOT build. warning not_signed: The bundle was made on a host that is not a Mac, so it is not signed. Apple silicon refuses unsigned programs: sign it on a Mac (codesign --force --sign - <app>).
Run the same commands on Windows, or on an Apple-silicon Mac, for NativeAOT builds. On a Mac the bundle Orchard.app is signed ad hoc, which lets it run on the Mac that made it; giving it to other people needs a Developer ID signature and notarization from your Apple developer account, which the tool doesn’t do.
TestResults/ was left by the C# tests. Only fonts/, art/ and data/ are shipped; other folders are listed under skipped.
Options and the JSON report
--target linux|win|osx (default: the host’s), --out <dir> (default export/), --project <dir|csproj>, --no-archive, --no-aot, --steam. The version in the names is the project’s <Version>, 1.0.0 when unset.
With --json the result lists every file with its size and SHA-256, the runtime (nativeaot or coreclr-self-contained), devTools: false, what was skipped and the warnings. Read the warnings in CI: they say why a build isn’t NativeAOT, a font without a licence text (font_licence_missing), or a file over 64 MiB (large_file).
Good to know
- Content folders are copied as they are:
fonts/takes.ttf .otfand their licence texts,art/takes.svg .png .jpg .jpeg .psd .webp, anddata/takes anything. - The game finds
fonts/next to the program, so the working directory doesn’t matter. - The repository’s docs list the C++ toolchain NativeAOT needs:
clangandzlib1g-devon Linux, the Visual Studio C++ tools on Windows. --liveon an exported program exits 5 withno_dev_tools.- Dedicated servers export with
--server, for linux-x64 only: see Client/server sync with a dedicated server. - Web, Android and iOS: see Export for the web, Android and iOS.
Every detail is in Exporting.