Why BASIC?
"We wanted to develop a language that would be easy for students in the liberal arts to learn, so that they could use it in their own work."
— John Kemeny and Thomas Kurtz, 1964
A Tradition Rather Than a Language
BASIC was never one language. It was a tradition — dozens of dialects across sixty years, each adapting to its environment. Dartmouth BASIC. Microsoft BASIC. Applesoft. Commodore. BBC. QuickBASIC. Visual Basic. BlitzBASIC. QB64. None were wrong.
What held the tradition together was a single principle: computing should be approachable. Kemeny and Kurtz built the first BASIC so liberal arts students could sit down at a terminal and make the machine do something. Every dialect inherited that principle, whether it admitted it or not.
General-Purpose Languages Won for Good Reasons
And yet BASIC stopped evolving somewhere in the 90s, and it's worth being honest about why. For a while, many of us used BASIC — Visual Basic especially — for serious work. And then we outgrew it. Not because BASIC was bad, but because the domains we were working in had grown genuinely unbounded. Windows GUI development is vast: threading, networking, databases, enterprise testability, decades of API surface, unpredictable requirements. That kind of domain rewards general-purpose languages with strong structural apparatus. C# and its peers didn't win by cultural prejudice. They won because the domain had outgrown what a BASIC could reasonably offer.
The mistake wasn't in leaving BASIC behind for general-purpose work. The mistake was in concluding BASIC was obsolete. It wasn't obsolete. It was being asked to do the wrong job.
Domain-specific languages win in bounded domains. General-purpose languages win in unbounded ones. These are different tools for different problems, and pretending one replaces the other is how BASIC got written off.
Domain in the Grammar
2D games are a bounded domain. There's a knowable set of things every 2D game needs: a render loop, sprites, input, audio, collision, state machines for character behavior, scene management, asset loading, persistence. You can map the territory. And when a domain is mappable, a language built for that domain beats a general-purpose language with libraries — because the language itself encodes the domain's mental model.
This is the move modern 2D engines have never quite made. Unity, Godot, GameMaker — they all reach for general-purpose languages (C#, GDScript, GML) and then bolt on APIs, frameworks, node hierarchies, and conventions to approximate the shape of a game. You spend as much time learning the engine's dialect of conventions as you do making the game. The language has no opinion about what you're building. The engine supplies the opinion, awkwardly, through API surface.
Crash BASIC takes the other path. The language itself knows what a 2D game is. SPRITE, PATTERN, BEHAVIOR, SCREEN, LAYER, SCENE, MAP — these aren't library calls. They're grammar. Declaring a character's behavior, parking an animation until a dialog beat lands, loading a map and spawning entities from its metadata — these are a few lines of code that read like intent, because the language is fluent in the domain.
Domain in the Runtime
There's a second consequence of domain commitment that's even harder to fake: the runtime can be built for the same domain the language is built for.
A general-purpose runtime has to accommodate whatever you might be doing. It can be tuned — and good 2D engines tune very well — but the tuning happens on top of a layer of generality that exists because the engine doesn't know in advance what kind of program it's running. The performance is achievable. The question is how much of it you have to earn.
Crash BASIC's runtime knows exactly what kind of program it's running. A 2D game. With sprites, layers, a tick loop at a known rate, a finite set of audio channels, a known collision model. That knowledge lets the runtime make the right decisions by default, so developers don't have to spend development time making them. It's very possible to write a game in Crash BASIC that runs at 60+ FPS without its developer needing to profile, batch, or optimize. It just runs. That's the point.
For you, the developer, this shows up as time you get back. You aren't chasing frame pacing issues before your game is even fun yet. You aren't fighting asset pipelines to hit 60fps on a phone. The runtime handles the parts of performance that are about being a 2D game engine, so you can spend your time on the parts of performance that are about your specific game. Make a game, not an engine-tuning project.
The Feedback Loop
There's one more thing about BASIC that modern languages lost and never really got back: the speed of the loop.
When you write BASIC, you aren't waiting. You type a line. You run it. It runs. You see what happened. If something went wrong, the error tells you what — in plain English, pointing at the line that broke. You change it. You run it again. The cycle from intention to result is measured in seconds, not minutes. No compile step. No project rebuild. No deploy pipeline. No waiting.
This is the thing QBasic got right for a generation of kids. You could type CIRCLE (160, 100), 50 and see a circle, right now, and then change it and see a different circle, right now. That tight loop is what made programming feel like making things — not like filing paperwork with a compiler. A lot of us became developers because of that feeling. And a lot of us spent the next twenty years missing it, as modern development quietly stretched the loop out into the kind of wait time that kills momentum and, for some of us, kills projects.
Crash BASIC is built around the short loop. No compile step. Plain-English errors that point at the line that broke. Documentation attached to every keyword — hit F1 anywhere in the IDE and the relevant help is right there, not in a browser tab you have to alt-tab to. The in-browser playground means even the install step is gone: open the page, type, hit run, see it move. The loop is as short as we could make it, because the loop is the point.
For some developers this is a nice-to-have. For others — and you probably know who you are — it's the difference between shipping a game and abandoning it. When your working memory and your attention have to survive every gap in the feedback cycle, short loops aren't a feature. They're life support for the project.
The loop is what made BASIC magical in 1964, and in 1985, and in 1993. It's still what makes BASIC magical. We just had to build a modern version of it.
A BASIC That Knows What It's For
That's what BASIC is for. Not a general-purpose language that tries to do everything and ends up being nothing in particular. A domain-committed language whose grammar — and whose runtime — is the shape of the thing it builds. Visual Basic was that for Windows GUIs in its era. BlitzBASIC and DarkBASIC were that for their game niches. BBC BASIC was that for the BBC Micro. The BASICs that thrived were the ones that picked a domain and committed to it.
Crash BASIC is that commitment, for 2D games, made on purpose and for a modern era: threading, shaders, plain-English errors, cross-platform from phone to desktop to console, all coherent because they're all pulling the same direction. The language encodes the domain. The runtime optimizes for it. The feedback loop keeps you in flow while you build.
It isn't retro. It isn't preservation. It's the next dialect in a tradition that never should have stopped evolving — the first BASIC to encode a full domain in its grammar and in the runtime beneath it, so developers get back the time general-purpose engines quietly take.
Welcome to a BASIC that knows what it's for.