Crash-tan Crash-tan

Build all the things!

Crash BASIC 1.42.0 Release Notes

written by Crash-tan

THE "SHIP IT EVERYWHERE" UPDATE

This one's about getting your game out the door — onto every desktop, from
whatever machine you happen to be sitting at.

Here's the headline I'm genuinely proud of: you can now build your game for
Windows, macOS, and Linux from a single computer — no matter which of those
you're running.
On a Mac? Hand someone a Windows build. On a Windows PC?
Produce a real macOS app. One machine, all three desktops. And the first time
you target a platform you don't have the build tools for, I'll go fetch them
myself so you don't have to.


Build for every desktop, from any desktop

Packaging used to mean "build for the platform you're standing on." Not anymore.
Point me at your game and pick your targets — in the Package screen, just tick
Windows, macOS, and Linux no matter what you're running, or from the command
line:

crashplayer package mygame.crashcart --platform windows,macos,linux

You get a ready-to-run build for each: a Windows folder, a macOS .app, a Linux
folder — all from the one computer. The first time you target a platform whose
build tools aren't installed yet, I'll offer to grab them and then carry right
on. No compiler scavenger hunt.

Building a Mac app on Windows? A few finishing touches on the Mac

Some things only a Mac can do, so if you build the macOS .app on Windows,
the first time it lands on a Mac you (or whoever you send it to) finish it
there — just 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

# And give it a signature — a build made off a Mac comes out unsigned:
codesign --force --deep --sign - YourGame.app

Then it launches. (Built it on a Mac in the first place? None of this applies —
it's all handled for you.) And whenever a build comes out unsigned, I'll tell
you plainly rather than pretend otherwise.


Lighter on its feet

Under the hood I went on a bit of a diet. CrashPlayer — and the games you
package — used to carry a couple of separate media libraries around for sound
and video. Those are built right in now: no loose files riding shotgun next
to your game, nothing to misplace, and one less thing to go wrong on someone
else's computer. Sound and video work exactly as before — the bundle's just
tidier and more self-contained. (Which is the whole point.)


JMES() — reach into your data in one line

Got a chunk of JSON-shaped data — a config, a save file, a roster, an API
response — and you need one thing out of deep inside it? JMES(data, "query") runs a JMESPath query and hands you back the
answer as a normal Crash value:

data = DESERIALIZE$(json$)

' Reach a nested field
PRINT JMES(data, "players[0].name")

' Run a function over an array
best = JMES(roster, "max(players[*].score)")

' Filter, then take the first match
winner$ = JMES(roster, "players[?score > `100`].name | [0]")

Objects come back as objects, arrays as arrays, numbers and strings as
themselves, and a query that matches nothing gives you 0 — the same convention
as DESERIALIZE$. No more hand-walking a nested tree to fish out a single value.
(A bad query stops loudly and tells you, rather than guessing.)


SET SPRITE ... FRAME — flip a frame, nothing else

Animating a sprite by hand? You no longer have to re-state its position and image
just to change which spritesheet cell it's showing. SET SPRITE n FRAME f
changes the frame all on its own:

SET SPRITE 0 FRAME 2                  ' just switch to cell 2

SET SPRITE 0, x, y, "hero" FRAME 3    ' ...or set the frame while you place it

Frames are 0-based. This is purely a tidier way to nudge one frame — your
existing SET SPRITE n, x, y, img, frame calls parse exactly as they always did.


Fixes

  • Packaged games launch reliably however they're started. A double-clicked
    or app-launched build could quit partway through play depending on where the
    system happened to start it from. It now sets up its own workspace on launch,
    so it behaves the same whether you run it from a terminal or double-click the
    icon.
  • Friendlier cloud-save messages on iOS when you run into iCloud's storage
    limits, plus a guard against oversized carts — clear words instead of a
    mystery failure.

Compatibility

Nothing here changes a line of the code you've already written.

  • JMES and SET SPRITE ... FRAME are brand-new — they don't touch anything
    existing, and the familiar SET SPRITE n, x, y, img, frame still parses just
    as before.
  • The packaging changes are about building your game, not about the language —
    your .crashcart is unchanged.