The comment was short: “you SURE its you porting it and not claude”. The post was about getting SHOCKWAVE — my own game, written for the Vectrex — running on an Atari 2600. So the thing in question was my own game, rebuilt for a machine with 128 bytes of RAM. I have been writing software professionally for thirty years, and games for machines like this one for longer than that. The question now turns up under every post, usually with the same subtext: if a model helped, the work doesn't count.
Here is what I actually think. A frontier model today writes better code than I do, faster than I do, in more languages than I know. That is not a concession, it is just where we are. And no, that does not stop at retro hardware either. Someone will point a good model at a 6502 and a cycle-exact emulator and it will get there.
I still write every line of my games myself. Not out of pride, and not because the machine can't — but for reasons that have nothing to do with whether the code could be generated.
Why by hand
- Know-how. A Vectrex has no frame buffer. The beam draws line by line, and every line costs brightness and adds flicker. There is a hard budget for how much you can put on screen before the whole picture starts to wobble. You don't learn where that budget sits by reading about it. You learn it by burning three evenings on a track that looked fine in the emulator and shook on the real tube.
- Maintenance. I ship cartridges. A box that goes out has to work on a machine from 1982 that has been sitting in an attic for twenty years, with a CRT whose calibration drifted a decade ago. When something breaks, I need to know why — not read my own code like a stranger.
- Optimisation. The interesting work on these machines is squeezing. Fewer lines, tighter loops, one less branch in the inner routine. That is not a chore on the way to the game. That is the game, from where I sit.
- Fun. In my day job, AI has already taken most of the typing. Writing code is down to maybe twenty per cent of what I do; the rest is reviewing what a model produced, steering it, and the usual meetings. That is where the work is going, and arguing with it would be pointless. But the part I actually fell in love with is now the small part. Retro coding is where I get it back. I am not handing that over too, just to save an afternoon.
The constraints I picked
Three rules, held since the start, and all three are about the same thing: keeping the game separate from the machine it runs on.
C, not C++. Plain C compiles for everything from an Atari 2600 to a Vision Pro. No exceptions, no templates, no runtime I would have to port. One codebase, one language, from an 8-bit cartridge to a spatial headset.
No engine, no SDK, no third-party game code. Nothing from Unity, nothing from Unreal, no middleware. If a platform needs something, I write it for that platform, in that platform's folder, and the game code never learns about it.
Vector, not pixels. This one is the least obvious and the most useful. A vector game is maths all the way down — points, matrices, projection. There is no hand-drawn art to redo per machine. Pixel art does not travel: a sprite sheet for a Game Boy Color is worthless on a Vectrex. A track defined as geometry runs on both, and on a headset too. That is why almost everything I have shipped so far is vector. It changes in 2027, and I know what that will cost me.
Here is what those rules buy. This is SHOCKWAVE, my anti-gravity racer, counted today:
| Layer | Lines | What it is |
|---|---|---|
| Game | 12,119 | rules, physics, tracks, AI, menus |
| Render + system | 2,383 | shared drawing and plumbing |
| Vectrex cartridge | 581 | platform layer |
| + cart firmware | 2,335 | runs on the RP2350B, drives the vector hardware |
| + cart SDK | 742 | the API a game is written against |
| SDL (desktop) | 450 | platform layer |
| visionOS | 1,485 | platform layer |
| Atari 2600 | 1,981 | rewritten, not shared — 1,297 C + 684 lines of 6502 |
581 lines are what it takes to attach that game to a console from 1982, and the same 12,119 lines of game code drive it on a Vision Pro. Nothing in the game folder knows which machine it is on — that is the whole point of the rules, and it is why I guard them.
The Atari 2600 is the exception that proves the rule, and it is the one that comment was about. 128 bytes of RAM and no frame buffer means nothing is shared: the whole game is rewritten, 1,297 lines of C and 684 lines of 6502 by hand, into a 32 KB ROM. Not one line of the 12,119 made it across. Same game, same tracks, same feel — built again from nothing, because that machine does not let you bring anything with you.
The cartridge is its own thing, and that is where the real work went. 2,335 lines of firmware run on the RP2350B: after the boot screen the cart halts the console's 6809 and drives the vector hardware itself, one core running the game, the other redrawing every 20 ms. On top of that sits a 742-line API that any game can be written against. The console does the drawing, the cartridge does the thinking, and none of that existed before I built it.
Where the AI actually sits
Now the part people get wrong when they ask the question. I use AI daily. Just not where they assume.
It does not touch game code. Not one line. What it does instead is check what I wrote, and it is better at that than I will ever be.
The useful part is not unit tests, though it writes those too. It is the gameplay runs. A model plays the game — properly, for minutes at a time, across tracks and ships and edge cases — and on every single frame it verifies the non-functional requirements. Frame time against budget. Lines on screen against the brightness limit. ROM size against what fits on the cart. Memory against what the machine has.
That matters because of how this hardware fails. A broken line of C throws an error. A frame that takes 2 ms too long does not throw anything — it just makes the picture flicker on one machine in ten, and you find out when a buyer emails you. Catching that needs someone to play for hours and watch a number the whole time. No human does that well. A model does it on every frame without getting bored.
Beyond that it writes tools, not game code. Scripts that port data between platforms, that optimise level tables, that pack assets, that convert a track from one format into another. Those tools are allowed to be throwaway, and they often are. The game code is not.
I don't let it write the game. I let it prove the game is still within budget — on every frame, for hours, which is exactly the job I am worst at.
Prototypes are the exception
There is one place where I do let a model write game code, and I should say so plainly: prototypes. Before anything gets near a cartridge, the question is whether the thing is actually fun. That is not a question you answer on paper or in a design document. So I let it build a rough version, playable in an afternoon, and then I play it.
Two rules hold. It builds on my platform code, not on whatever would be quickest. A prototype that runs in some forgiving sandbox tells me nothing about whether the game works on the real machine with the real budgets — that is the entire thing I need to find out. And none of it survives. It is throwaway code, deliberately, and it is worth more that way: a prototype answers one question, and once I have the answer it has done its job.
Neither VEXXON nor SHOCKWAVE came out of that process. I started VEXXON three years ago and SHOCKWAVE about eighteen months ago, both long before I worked this way. They were built the slow way, by hand, from the first line — which is also why the question under my posts is easy to answer for those two in particular.
The uncomfortable part
Everything above probably reads like a defence. It is not, and I would rather say the next bit plainly than have it read as one.
The frontier models already out-code me on raw output. Not in some narrow benchmark sense — in practice, on real problems, at speed. Anyone who has worked with the current generation daily and says otherwise is either not using them properly or protecting their self-image.
And retro programming is not safe from that. The constraints are tight, which people think protects the field, but tight constraints are exactly what a model with a cycle-exact emulator and a feedback loop is good at. Give it the hardware in the loop and it will learn where the brightness budget sits, the same way I did, only faster. I expect to see very good generated 6502 within a few years.
So I build things that are harder to copy
Which is why my projects have been drifting toward work that does not reduce to writing code.
SHOCKWAVE does not ship as a ROM. It ships on its own cartridge — a board I designed, with an RP2350B on it that takes over the console's vector hardware after the boot screen. Getting that right meant schematics, a board house, firmware, a shell, a label, a manual, customs declarations and a morning at the post office. A model can write the 6809 side of that. It cannot design the board, get it manufactured, or stand in the queue at the post office with a crate of them.
The other direction is data. A solid model of a track, a level, a game's content — how it is structured, what can be expressed, what the tooling around it allows — is worth more than the renderer that draws it. Code gets rewritten. A good format survives three ports.
Neither is a moat that holds forever. Both buy time, and both happen to be the parts of this work I enjoy anyway.
And this is the part I am still better at than any model: not writing code, but shipping products — real ones, that a real customer ends up holding in their hands.
So: did I port it myself? Yes — my own game, onto a machine I had to learn from scratch. Could a model have done it? Probably, with some help and a few false starts. Does that change why I sat down and did it? Not in the slightest.
Somebody will point out that this is sentimental rather than rational. They are right, and I don't mind. I spend my working days reviewing other people's code and sitting in planning meetings. For a few hours a week I get to count cycles against an electron beam on a machine older than most of the people asking the question.
That part I'm keeping.