Skip to content

Distribution

When development wraps up, getting your game into players' hands should be effortless.

Distributing a project folder full of scripts, audio, and images is impractical and risky, as users can easily delete critical files.

Nutshell makes distribution easy via Bundling (packaging your project directory into a project bundle) and Compiling (compiling a project into a standalone executable for a seamless, single-file distribution).

Nutshell loading order

When launched, Nutshell resolves its execution target through a strict hierarchical fallback sequence:

  1. Command-line arguments: If any arguments are provided, Nutshell treats the first argument as either an explicit bundle file or a target source script/directory path.
  2. Compiled executable bundle: If no command-line arguments are provided, it checks whether the currently running binary has a game bundle fused directly into it.
  3. Local bundle: If the binary is not fused with a bundle, it scans the current working directory for any file with a case-insensitive .nsz extension and loads the first match.
  4. Default Script: If no bundles are found, it looks for the main.nut entrypoint script in the current working directory.
  5. If all previous steps fail to locate a valid script or bundle, Nutshell prints an error message and terminates.

Bundle

A bundle is simply a standard ZIP archive containing your main.nut file and all associated game assets. That's all.

You can distribute only a bundle, and anyone with Nutshell can run your game!

When Nutshell loads a bundle, it seamlessly mounts the archive as the active project root. The engine treats the internal structure of the ZIP exactly like a physical directory on the disk.

This means that if you load res://images/acorn.png in your script, it works identically whether acorn.png is an actual file on disk while you are developing or an entry compressed inside your archive.

For more details on how paths are resolved dynamically, refer to the Paths section.

Bundling via Command Line

You can generate a bundle using the bundle command. Pass the path to your source folder as argument (defaults to the current working directory).

nutshell bundle [source_path]

Executing nutshell bundle on your project folder will automatically package it into a bundle in your current directory.

You can customize the bundling process using flags:

  • --out or -o: Specifies the output bundle name (default: game.nsz).
  • --compression or -c: Sets the compression level (0 = Store/None, 1 = Fast, 9 = Best, -1 = Default).

Here is an example:

nutshell bundle ./adventure_project -o adventure.nsz -c 9

main.nut entrypoint

Both the bundle and compile commands perform pre-flight validation.

If the source directory or archive does not contain the main.nut required entrypoint script, the command will immediately fail with an error.

nsz extension isn't mandatory

You can package your bundle with any extension, but keep in mind that only the nsz extension is scanned by default by Nutshell when run without any argument or launched by double clicking and not compiled with a bundle.

Bundles using other extensions must be passed to the executable explicitly or dropped onto it.

What does nsz stand for?

It stands for NutShell ZIP.

Or Nut Storage Zone. Or Neatly Squeezed Zeroes.

Or maybe even Non Suspicious Ziploc.

Or was it for Nappy Squirrel Zzz?

Honestly, I don't remember how I came up with it. The original git commit has been lost to the sands of time, but hey: it sounds freaking cool and that's all that really matters.

(And no, it has absolutely nothing to do with a certain Big N console, so please put away the cease-and-desist letters, corporate legal ninjas.)

Running a bundle

If an uncompiled Nutshell binary is executed without arguments, it will automatically scan the current working directory and load any *.nsz bundle it finds.

This allows for a simple distribution pattern where you distribute a small Nutshell binary alongside a massive archive file.

You can also run any bundle by passing the archive path directly to Nutshell as argument:

nutshell adventure.nsz

Compiling

Compiling takes bundling a step further. It compiles a project into a standalone executable by embedding the bundle directly into the Nutshell executable.

The result is a single, self-contained executable file that users can simply double-click to play your game: No installation, no extracting, no external files!

Creating a Compiled Executable

You can instruct Nutshell to compile the project into an executable using the compile command.

nutshell compile [source_path]

You can customize the output using flags:

  • --out or -o: Specifies the output executable name (default: game or game.exe).
  • --compression or -c: Sets the compression level (0 = Store/None, 1 = Fast, 9 = Best, -1 = Default).

As an example:

nutshell compile ./adventure_project -o adventure

Compiled executable vs local bundles

Note that if you are running a compiled executable, Nutshell will always prioritize its embedded internal bundle over external local archives unless passed as arguments.

Windows executable resource flags

When creating a compiled executable on Windows, you can customize the binary resources with your own, directly from the command line:

Flag Resource
--icon or -i Image file to embed as the application icon.
--app-version Application version string.
--product-name Product name string.
--company Company name string.
--copyright Legal copyright string.
--description File description string.
--comments Additional comments string.
--trademarks Legal trademarks string.
--manifest Path to a custom XML manifest file.

As an example:

nutshell.exe compile .\adventure_project -o Adventure.exe -i .\assets\icon.png --product-name "My Adventure Game" --app-version "1.0.0"

Extracting

If you have a compiled executable and need to extract the original host executable binary or the internal game assets, you can reverse the process using the extract command.

This command extracts the project bundle and host executable from a compiled executable.

Adventure.exe extract

By default, this command evaluates to the current running executable if no target is provided. You can also specify an external compiled binary as an argument:

nutshell extract Adventure.exe

You can customize the extraction paths using flags:

  • --out-exe or -e: Output path for the extracted host executable (defaults to <target>_source.<ext>).
  • --out-bundle or -b: Output path for the extracted project bundle.

Updating

Replacing the embedded bundle inside a compiled executable without rebuilding it from scratch is possible.

This is extremely useful when distributing small updates or when operating headless game servers, as it allows you to swap out the internal game archive instantly.

Adventure.exe update <new_source_path>

By default, this replaces the embedded bundle in the current running executable. You can target a specific compiled file using the --target flag:

nutshell update ./my_update_dir --target server.exe -c 9

Available flags:

  • --target or -t: Path to the compiled executable to update (defaults to current executable).
  • --compression or -c: Compression level if updating with a directory (0 = Store/None, 1 = Fast, 9 = Best, -1 = Default).

OS Limitations and the update Command

The update command creates a temporary file to copy the original executable binary and append the new bundle, ultimately attempting to replace the target atomically.

Its behavior on a currently running game depends heavily on the host operating system:

  • Linux: The OS tracks files via inodes. Updating a running executable seamlessly renames the disk path to the updated binary without disturbing the active process.
  • Windows: The OS locks active executables. When replacing a running process on Windows, Nutshell uses a fallback to rename the active executable to a .old backup file before replacing the target.

Large Game Archives

While compiling is incredibly elegant for small projects and utilities, it is not recommended for games with massive file sizes (e.g., hundreds of megabytes or gigabytes of assets).

Appending massive archives directly to the executable creates heavily bloated binaries that can trigger OS-level size limitations. Furthermore, updating a massive compiled binary via the update command requires duplicating the original executable binary and rewriting the new bundle entirely, which is heavily inefficient for enormous file sizes.

Distribute your bundle!

For large projects, it is highly recommended to distribute your game as a bundle.

Keep the Nutshell executable standalone, and distribute your game assets as a separate bundle.

When updates occur, players only need to download and replace the external archive. Unless you need to update Nutshell itself, obviously.