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:
- 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.
- 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.
- Local bundle: If the binary is not fused with a bundle, it scans the
current working directory for any file with a case-insensitive
.nszextension and loads the first match. - Default Script: If no bundles are found, it looks for the
main.nutentrypoint script in the current working directory. - 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).
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:
--outor-o: Specifies the output bundle name (default:game.nsz).--compressionor-c: Sets the compression level (0= Store/None,1= Fast,9= Best,-1= Default).
Here is an example:
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:
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.
You can customize the output using flags:
--outor-o: Specifies the output executable name (default:gameorgame.exe).--compressionor-c: Sets the compression level (0= Store/None,1= Fast,9= Best,-1= Default).
As an example:
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.
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:
You can customize the extraction paths using flags:
--out-exeor-e: Output path for the extracted host executable (defaults to<target>_source.<ext>).--out-bundleor-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.
By default, this replaces the embedded bundle in the current running executable.
You can target a specific compiled file using the --target flag:
Available flags:
--targetor-t: Path to the compiled executable to update (defaults to current executable).--compressionor-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
.oldbackup 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.