Follow these steps to distribute your Crash BASIC games outside the Arcade.
Updated 6/11/2026
Step 1: Choose Your License Tier
You will need a Crash BASIC Arcade account to sell your games commercially. Your license tier determines your distribution rights:
- Free — Share on the Arcade without a splash screen, or distribute on desktop/mobile/embedded with a splash screen (non-commercial use)
- Indie — License to sell games commercially (skippable splash screen)
- Studio — Full commercial rights (removable splash screen)
For non-commercial use, signing up for Crash BASIC Arcade is not necessary, but you will miss out on a lot of the fun!
About stamping: When you export a
.crashcartfrom the Crash BASIC IDE, you can also select to stamp your crashcart if you've linked to Crash BASIC Arcade with an active subscription. The stamp is what determines splash-screen behavior at runtime — no separate stamping step is needed before packaging.

Step 2: Package Your Game
CrashPlayer's built-in packager bundles your .crashcart together with the CrashPlayer runtime into a distributable app for Windows, macOS, or Linux. Use either the GUI or the command line. You can download CrashPlayer here
Option A — GUI Launcher
Open CrashPlayer with no arguments to launch the GUI:
crashplayer
Click the 📦 Package tab. Drop or browse for your .crashcart — the form auto-fills the game name and icon from the cart's manifest. Pick your target platforms (Windows, macOS, Linux, iOS, Android), set the default window size and fullscreen preference, choose an output folder, and click Package. Progress and the path to each output appear in the log below.
Note that you MUST have Rust installed for it to output a standalone binary. First compilation will take a while. After that, it's fast!
[Setting Up Rust] (https://rust-lang.org/tools/install/)
Option B — Command Line
Bundle a .crashcart file into a redistributable app.
- Desktop (
windows,macos,linux) → a standalone, double-clickable player app with your game embedded. - Mobile (
ios,android) → a ready-to-open Xcode / Android Studio (Gradle) project.
You can build any desktop target from any host — a macOS .app from Windows or Linux, etc. Some finishing touches only a Mac can apply, so a .app built off a Mac needs three one-time steps on a Mac before it launches (see Building a Mac app off a Mac).
crashplayer package <crashcart> [game-name] [options]If [game-name] is omitted, it's read from the crashcart manifest's game_name. If --icon is omitted, an embedded icon.png in the cart is used when present.
Positional arguments
| Argument | Required | Description |
|---|---|---|
<crashcart> |
yes | Path to the .crashcart file to package. |
[game-name] |
no | Display name. Falls back to the cart manifest's game_name. |
Options
Platform & output
| Flag | Value | Default | Description |
|---|---|---|---|
-p, --platform |
comma-separated list | host platform | Targets: windows, macos, linux, ios, android. |
--all |
— | — | Build all desktop platforms (win/mac/linux). Overrides --platform. |
-i, --icon |
path | embedded icon.png, else default |
Icon file (PNG recommended). |
-o, --output |
dir | . |
Output directory. |
Platform names also accept common aliases (win/win64, mac/darwin/osx, iphone/ipad). With no --platform and no --all, it builds for the host OS only.
Launcher behavior (desktop & mobile)
| Flag | Value | Description |
|---|---|---|
--window-size |
WxH |
Default window size, e.g. 1280x720. |
--fullscreen |
— | Launcher starts in fullscreen. |
--debug |
— | Launcher passes --debug to CrashPlayer. |
--no-escape-exit |
— | Disable Esc-to-exit. |
Mobile only (`ios` / `android`)
| Flag | Value | Description |
|---|---|---|
--bundle-id (alias --app-id) |
reverse-DNS id | Required for mobile. App bundle id / Android applicationId, e.g. com.yourstudio.yourgame. |
--orientation |
landscape | portrait | all |
Defaults to the cart manifest's orientation, else landscape. |
Packaging a mobile target without --bundle-id is a hard error.
Versioning & cache
| Flag | Value | Description |
|---|---|---|
--crashplayer-version |
version | Pin a CrashPlayer version instead of latest from the CDN. |
--no-host-binary |
— | Always download the prebuilt player from the CDN; never reuse the running binary. |
--refresh-cache (aliases --refresh-ffi, --no-cache) |
— | Ignore cached downloads (FFI lib, player bundles, mobile template zip) and re-fetch fresh. |
Signing & sealing (desktop / macOS)
| Flag | Value | Description |
|---|---|---|
--key |
64 hex chars | The cart's seal key (32 bytes). Compiles a native locked player that embeds the key, binding the exe to the cart. Needs Rust/cargo; host platform only. |
--key-file |
path | Read the seal key from a file (32 raw bytes or a 64-char hex string). |
--apple-signing-identity (alias --sign-identity) |
identity | macOS: Developer ID for a real signature (e.g. on CI's macOS runner). When packaging on a Mac, the default is an ad-hoc signature; a .app built off a Mac comes out unsigned (finish it on a Mac — see below). |
Building a Mac app off a Mac
The macOS .app builds fine from Windows or Linux. A few things only a Mac can
do, so the first time that build lands on a Mac, run these once:
# Windows can't set the Unix "executable" bit, so turn it on:
chmod +x YourGame.app/Contents/MacOS/YourGame
# Clear the "downloaded from the internet" quarantine flag macOS adds:
xattr -dr com.apple.quarantine YourGame.app
# Give it a signature — a build made off a Mac comes out unsigned:
codesign --force --deep --sign - YourGame.appBuilt on a Mac in the first place? None of this applies — it's handled for you,
and --apple-signing-identity lets you swap the default ad-hoc signature for a
real Developer ID.
Why lock your crashcart for distribution
By default a .crashcart is a plain bundle — anyone with the file can open it,
read your BASIC source, and pull out every sprite, sound, and song. Fine for
sharing and remixing; not what you want for a game you're selling.
Passing --key / --key-file packages a sealed build: the cart is
encrypted with that key, and the packager compiles a native locked player
with the key baked into the binary. The exe and the cart are bound together —
that player runs only that cart, and the cart runs only in that player.
Be clear-eyed about what this does and doesn't do. Locking is not DRM and it
won't stop a determined attacker. The decryption key ships inside the executable,
so anyone with the patience to reverse-engineer the binary, dump the decrypted
assets from memory while the game runs, or capture frames and audio at the
output can still get your content. Nothing that runs on someone else's machine
is ever truly safe.
What locking does do is raise the effort from "point any CrashCart reader at
the file and everything falls out" to "be a reverse-engineer." That gap is the
whole point:
- It stops casual ripping. The overwhelming majority of people who would
copy your assets will not crack a binary to do it. Removing the trivial path
removes most of the problem. - It protects your source. Your BASIC code — game logic, level design,
the actual cleverness — isn't sitting in plaintext for anyone to lift or
fork. - It makes theft deliberate, not accidental. Someone who breaks the seal
did so knowingly, which matters if you ever need to make a case about it. - It keeps honest people honest. A locked build signals "this is a finished
product, not a sample," and most people respect that.
Think of it like a lock on a door: it won't stop someone with a crowbar and
real intent, but it keeps the door from being something anyone can just walk
through. For paid or commercial distribution, lock it. For demos, jams, and
anything you want others to learn from or build on, ship it open.
Where the key comes from. You normally don't generate or manage the seal key
by hand — it's set when you export the crashcart from the IDE. The IDE
handles the key as part of the export, so the matching --key / --key-file
value is already established by the time you package; you just pass it through to
produce the locked native player.
See the --key / --key-file flags above, and the sealed build example
below.
Examples
# Package for all desktop platforms with an explicit icon
crashplayer package mygame.crashcart --all -i icon.png -o dist/
# macOS only, fullscreen, name pulled from the cart manifest
crashplayer package mygame.crashcart --platform macos --fullscreen
# Windows + Linux, fixed window size
crashplayer package mygame.crashcart -p windows,linux --window-size 1280x720 -o dist/
# Generate an iOS Xcode project
crashplayer package mygame.crashcart --platform ios \
--bundle-id com.studio.mygame -o dist/
# Generate an Android Studio project, portrait, with icon
crashplayer package mygame.crashcart --platform android \
--bundle-id com.studio.mygame --orientation portrait -i icon.png
# Sealed native desktop build (locked player embedding the cart key)
crashplayer package mygame.crashcart --platform macos \
--key-file mygame.key \
--apple-signing-identity "Developer ID Application: Studio Name (TEAMID)"
# Pin a player version and bypass all caches
crashplayer package mygame.crashcart --all \
--crashplayer-version 1.42.0 --refresh-cacheResolution rules (when a value is omitted)
- Game name →
[game-name]arg → cart manifestgame_name→ error. - Icon →
--icon→ embeddedicon.pngin the cart → bundler default. - Orientation (mobile) →
--orientation→ cart manifestorientation→landscape. - Platform →
--all→--platform→ host OS.
Android (Indie/Studio tier)
Publish your game as a standalone app on Google Play. Requires: Android Studio, Google Play Developer account ($25 one-time)
- Download the Android template from the Crash BASIC IDE.
- Drop your
.crashcartinto the template's game folder. - Follow the instructions in the template's
README.mdto build the AAB and upload to Google Play.
iOS (Indie/Studio tier)
Publish your game as a standalone app on the App Store. Requires: Mac with Xcode, Apple Developer Program ($99/year)
- Download the iOS template from the Crash BASIC IDE.
- Drop your
.crashcartinto the template's game folder. - Follow the instructions in the template's
README.mdto open in Xcode, sign, archive, and submit to the App Store.
Step 3: Distribute
Your game is now packaged and ready to share:
- Windows — Zip the output folder and share
- macOS — Distribute the .app bundle directly or zip it
- Linux — Zip or tar the output folder
- iOS — Submit to the App Store via Xcode
- Android — Submit the .aab to Google Play Console
- Web — Share a link to your game on the Arcade