Recursive AI

Export for Linux, Windows and macOS

All onegame recipes

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

Terminal
onegame export --target linux
Text
exported 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.
Text
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:

Terminal
export/orchard-1.0.0-linux-x64/run.sh --headless --frames 60 --json
Text
{"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:

Terminal
onegame export --target win
Text
exported 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.
Terminal
onegame export --target osx
Text
exported 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 .otf and their licence texts, art/ takes .svg .png .jpg .jpeg .psd .webp, and data/ 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: clang and zlib1g-dev on Linux, the Visual Studio C++ tools on Windows.
  • --live on an exported program exits 5 with no_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.