Manual

Packaging games

cargo xtask package -- --project samples/unity/CoinDash --out dist/CoinDash
cargo xtask package -- --scene dotnet/samples/scenes/showcase.json --scripts path/to/Game.dll --out dist/Showcase --title Showcase

makes a folder to ship:

PathWhat it is
<Title>.exeThe release player, named after the game
game.jsonWhat to play: the scene or project, script assemblies, window title, size and icon, the asset cache
game/The game's files: a Unity project's Assets, Packages and ProjectSettings (and its compiled scripts in Library), or a JSON scene's folder
scripts/A JSON scene's script assemblies
managed/The managed runtime: Tassix's UnityEngine, packages and runtime
dotnet/The .NET 10 runtime it runs on, so players don't install .NET
cache/Cooked assets

The player reads game.json when its command line names nothing to play, so the game starts with a double-click, and it still takes options such as --headless or --screenshot. Keep a JSON scene's assets under its folder: the folder is what gets copied.

The window's icon is a Unity project's own (Player Settings: the Standalone icon, else the default icon), else the image --icon names (copied in as icon.png and named in game.json), else the Tassix icon. On Windows the executable shows the same icon in Explorer and the taskbar: packaging asks the player for it (<Title>.exe --export-icon icon.ico, at 16 to 256 pixels) and writes it into the executable's resources, in place of the Tassix icon the player is built with (apps/player/tassix.ico).

Packaging runs the game once headless. That cooks its imported models and decoded images into cache/ (memory-mapped archives, loaded without importing again) and compiles a Unity project's scripts, so the packaged game starts without that work.

NativeAOT

cargo xtask package -- --project samples/unity/CoinDash --out dist/CoinDash --aot

compiles the managed runtime and the game's scripts ahead of time with NativeAOT into one native library, managed/Tassix.Native.dll, which the player loads instead of starting .NET. The package has no dotnet/ folder and no IL. For the Coin Dash sample:

JIT packageNativeAOT package
Size105 MB53 MB
Start to first frame (headless)0.22 s0.09 s
Frame time, 5000 scripted objects0.30 ms0.30 ms

What a NativeAOT build gives up is what needs a JIT: scripts can't hot reload, MCP's exec doesn't run, and new script assemblies can't be loaded after packaging (the scripts are compiled in). Scripts are still found and called by reflection: the engine and script assemblies are kept whole, and cargo xtask conformance-aot runs the conformance suite on a NativeAOT build (CI runs it). Generic instantiations over value types that only reflection makes (MakeGenericType) may be missing.

NativeAOT needs the platform's native linker: on Windows, Visual Studio with the C++ build tools.

Not yet

Installers, code signing, trimming the managed runtime of the JIT package (the MCP server's Roslyn ships with it), and packages for other platforms.

From docs/packaging.md in the repository.