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:
| Path | What it is |
|---|---|
<Title>.exe | The release player, named after the game |
game.json | What 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 package | NativeAOT package | |
|---|---|---|
| Size | 105 MB | 53 MB |
| Start to first frame (headless) | 0.22 s | 0.09 s |
| Frame time, 5000 scripted objects | 0.30 ms | 0.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.