Crash-tan
CrashCore 1.20.0 is out!
Crash BASIC 1.22.0 Release Notes
written by Crash-tan
THE "SHIP IT YOURSELF" UPDATE
Cross-platform game packaging, built right into CrashPlayer — plus a couple of runtime quality-of-life fixes that came out of wiring it up.
New crate: crashpackager
One library, two entry points, one set of bundle outputs.
crashplayer package <crashcart>— new subcommand on CrashPlayer itself. Auto-fills the game name from the crashcart's manifest, uses your currently-running CrashPlayer as the bundled binary for your host platform (skipping a CDN roundtrip), downloads artifacts for other platforms from the CrashPlayer CDN on demand.crashpackager— standalone CLI with the same flags. Drop-in for CI/GitHub Actions, no dependency on the full CrashPlayer player.- New "📦 Package" tab in the CrashPlayer launcher GUI — drop a
.crashcartonto the window, pick platforms, hit Package. Live step log, same output as the CLI.
Outputs per platform:
- Windows: folder with
crashplayer.exe, your crashcart, a.cmdlauncher,icon.ico(if you supplied a PNG), and a README. - macOS: proper
.appbundle with Info.plist, launch shim, dylib symlinks wired up. Icon conversion viasips/iconutilwhen building on macOS. - Linux: folder with the binary,
.shlauncher,.desktopentry for menu integration, optional icon.
Packager reads icon.png out of the crashcart when the GUI is used and auto-fills the icon field — no separate step to export an icon if you embedded one.
One architectural tradeoff worth being explicit about: packaging for macOS requires being on macOS (DMG extraction uses hdiutil). Rather than silently degrade, the packager returns a clean SKIP: packaging for macOS requires a macOS host on non-macOS hosts. Answer for cross-platform CI: use a macOS GitHub Actions runner for the macOS leg of your matrix.
Window title reflects the game
Window title is no longer hardcoded to "CrashBASIC" / "CrashCore" / "CrashGFX Text Mode" depending on which code path initialized the screen. Instead:
- At crashcart load, the in-header manifest's
game_nameis read and installed as theGraphicsBus's default window title. init_default_screen(noSCREENcall),SCREEN w, hwithout a title arg, andSCREEN TEXTall use that name as their default.- Programs that pass an explicit title to
SCREENstill win — user intent trumps default, and the title can still be updated mid-run because winit'swindow.set_titleis called on subsequentCreateWindowcommands. - Splash phase also uses the game name (fixes the "splash window flashes 'CrashBASIC' then updates" flicker on supported platforms).
Launcher GUI rebuild
The launcher window was 1024×576 with a single-row of controls crammed along the bottom. Now it's 1024×340 with:
- Header artwork embedded as the backdrop (the whole window IS the art).
- Tabbed interface: ▶ Play and 📦 Package.
- Both tabs use a 2-column label/control grid with consistent spacing so they read the same.
- Window size + fullscreen live on both tabs — pick once, applies to whichever action (launch or package) you take.
- Drag-and-drop a
.crashcartonto either tab; the Package tab also auto-extracts and uses the embeddedicon.pngif there is one. - Title bar reads
CrashPlayer v1.22.0 dev © 2026 Crash Continuum LLCinline instead of two separate overlays.
macOS launcher hang fix
Launching crashplayer with no args from a terminal on macOS used to hang silently — the Finder-AppleEvent capture path calls NSApp.run(), and the scheduled performSelector:afterDelay: stop message doesn't reliably fire outside a proper .app bundle. The launcher reached eframe::run_native only when the binary was Finder-launched from inside the bundle; terminal launches sat in the Cocoa run loop forever.
Fixed: the AppleEvent capture now checks stdin.is_terminal() first. If you're at a TTY, no Finder event is coming, so we skip the capture entirely. Finder-launched .app bundles still hit the capture path normally.
Misc
- Eight new unit tests for packager platform helpers (
sanitize_name, etc.), CDN manifest parsing, host-binary detection. build-dist.sh/build-crashplayer-dist.shuntouched — still the source of truth for producing release artifacts that then get bundled by the packager.
Cumulative changelog for 1.20.0 → 1.21.4 (the preceding arc) lives in docs/CHANGELOG_1.20.0-to-1.21.4.md if you're catching up.