Vibe coding an Atari 2600 port of Fortnite

A mockup of a Fortnite cartridge for the Atari 2600

The fine folks at Amazon randomly sent me an email about some kind of "Build Games Challenge" where if I built a retro game using Amazon Q Developer's agentic coding tool I could get a t-shirt.

This offering seemed tailor made for me, as I don't have time to play video games, let alone make them, and I buy my t-shirts in bulk and wear the same plain navy blue shirt every day.

But I am willing to change my ways! So I embarked on a three hour tour to vibe code a retro game.

The first challenge: picking the game! "Retro" has a lot of meanings, but it usually is some combination of more than 20 years old and pixellated. It would probably have been easy enough to one-shot "make me a Tetris clone" since there are probably a bunch of those out there already that the AI models (it looks like Q uses Claude Sonnet) have trained on, but... then we'd have yet another Tetris clone out there.

So I of course picked Fortnite.

Fortnite isn't old enough to be considered retro, plus it's constantly being updated, so by itself it wouldn't qualify, but I figured making a retro-styled port of the game would work, and if we're going retro, why not go way back to the near-beginning and target the Atari 2600 as the platform?

In case you're not familiar, the 2600 was one of the first home video game systems, and by far the most popular of its generation. Released in 1977 and continuing production until 1992 (!) it sold an estimated 30 million copies, which isn't as impressive now since the iPhone can surpass that number in a month or two, but... it was a different time, and that was a lot of consumer electronics.

Remember how I said 1977? Technology was a lot more limited then, and further constraints to reduce the price point made the Atari 2600 an incredibly limited machine. You can argue that constraints are what make games great, and there are certainly some real bangers in the back catalog, but let's compare Fortnite's minimum system requirements against the Atari's capabilities:

Spec Fortnite Atari
Video card Intel HD 4000 on PC; AMD Radeon Vega 8 The TIA chip, which can output... stuff... to a TV
CPU Core i3-3225 3.3 GHz The 6507, a scaled down version of the 6502, running at 1.19 MHz
RAM 8 gigabytes 128 bytes

Oh, and without bank switching, which we won't even try to figure out, programs for the 2600 have to fit in 4 kilobytes of ROM, which I don't think is enough to even store the text in this post.

So, we have our work cut out for us. Or rather, Amazon Q does. I'm not writing a line of this thing. But I thought it'd be a great challenge - I hear about how some languages are better suited for LLM code generation because there are more examples out there on GitHub etc, but how many 6507 applications can there be?

Installing Q was pretty straightforward, and all I needed to do was open a new terminal window for it to take effect. It added some autocomplete options to the session, and running q chat got me up and running:

The launch screen for Amazon q chat

The promo docs said they had a generous free tier, and I didn't hit it in the three hours or so I was working, and responses were pretty quick. I'd previously used GitHub copilot and a lot of copy/paste with both ChatGPT and Claude web interfaces, but this was the first time I just used a terminal chat and didn't even look at the code.

The system has the ability to take actions on your computer, but you're in control of allowing it... kind of. Actions seem to be sorted into categories, and you have the choice of saying yes or no every time for a category, or selecting "trust" to let it happen every time. Categories are things like changing files, executing scripts, and so on.

An "allow this action" prompt in Q chat

Hilariously, the "y" and "t" options are right next to each other on the keyboard so I figured it would only be a matter of time before I accidentally enabled trust mode for an action, but I settled on trusting file writes and approving bash executions, just in case a rogue rm -rf / came along (it didn't.) But as with most things like this, I found myself treating the "y" key like a "yeah, whatever" button and didn't scrutinize the actions too closely before approving. But I had the illusion of control!

Now, back to the game. Before I even tried to design something I wanted to level set the capabilities of the system by trying to get something on the screen. Atari games run on cartridges, but for development I installed cc65 to build the assembly code and Stella to emulate a system. Q set me up with a Makefile so the development workflow was along these lines:

  • Prompt a change
  • q makes the change and asks permission to build
  • I say yes, and a new "ROM" is generated
  • Ctrl-R in Stella reloads the image and I review the changes

Interestingly, on a few occasions Q would do a build and then jump right into another set of changes without any feedback, like it had thought up a better way to do something while the code compiled. Conversely, there were a few times where it would make the code changes but I had to ask for a build.

When we got to a checkpoint where something was workable, I'd ask Q to commit to git, and it took care of all of that.

A git commit via agents

But I'm getting ahead of myself. Getting something on the screen was the hardest part of the project, which was kind of the point: I wanted to see if a modern LLM could even build workable 2600 code. There was about half an hour of getting things like this:

An attempt at a 2600 monocular screen that... isn't

That was supposed to be a solid green screen, I think. Eventually we got something running, but it was a lot of me saying "nope, not working" with a brief attempt to describe what I was seeing.

This part (and a lot of the later phases) reminded me of some jobs I've had where developers would just throw code back over the fence for user testing where it was clear they hadn't tried it at all. And in fairness, I guess that's the state of things right now. But if we don't have it at the time of this writing, I figure it won't be long before coding agents have some level of validation built into the workflow, either through assessing automated test results or actually looking at the screen. If I could have that, each phase would just be a prompt and a trip out for coffee while the machine figured things out, which would be a really interesting change (does Cursor or Windsurf do this yet?)

But after an hour or so we got to a "Hello World" screen, or at least the 2600 equivalent:

"Hello" on the screen

See the weird glitches where lines seem to start a little early or late? Get used to that. The 2600, as I understand it, was closely tied to CRT scanline output that televisions of the era used, to the point where the code actually had to time out instructions as the beam ran across the screen. I had a lot of sections where the screen would jump a line or two up or down, and the bottom line of the screen often was only half drawn.

But close enough! It was time to get going on the game. Obviously networked multiplayer was out, but I was envisioning something kind of like Atari's Combat game, with a 1v1 style play, maybe a few bits of scenery on the screen, and some weapons and medkits to pick up (there's only one button on the controller, so inventory management would be just "you get whatever you last picked up")

I also thought it'd be funny to have a "skin shop" where you could buy different colours of characters.

I was overly ambitious, but I think the limitations were more with the AI than the 2600.

Getting a player on the screen that I could move around took no time at all, and moving up and down was silky smooth. However, the system had a really hard time with left to right movement and I had to revert the code a number of times. I've played a few Atari games in my day, and I don't recall having trouble moving, say, the Space Invaders shooter back and forth, but the best the AI could come up with was a set number of fixed positions horizontally to move between, and if it got too close to the edge, the player would just disappear.

A player moving around, kind of, on a 2600 emulator screen

The next step was to get some scenery to dress up the playfield. That... did not go well. I'll spare you the high-strobe gif, but things looked more or less like this:

Terrible playfield

Once again, I reverted my changes to the last good commit and tried to get shooting to work. The LLM wasn't able to get the fire button to detect reliably, and again, left and right shots were problematic because scrolling was hard. To work around it, Q decided on its own to just have auto-fire based on the last direction (up down left right, you're dreaming if you think we're getting diagonals,) but that was after an amusing suggestion to use pressing up and down at the same time to simulate the fire button, which can be done in an emulator but not on an actual physical joystick.

Shots fired on the 2600

You can kind of see shots to the right and left, but it was inconsistent and terrible. Still, I needed shooting to make an enemy make sense in a Fortnite game, so I kept it and moved on to an enemy. I figured multiple bad guys would be too much of a stretch, so tried for a single opponent.

Here we ran into all the previous problems: the enemy couldn't move left or right either. I didn't even get into collision detection for people to actually get shot, because I could see that the game would be pretty unplayable as it was going.

Click to activate animation

So no scenery, no enemies... How exactly would this be Fortnite? And then it hit me: the storm. Staying in zone is a big part of the game, where the gameplay area continues to shrink over the course of the game to force players to come out of hiding and fight it out to the last one standing. My port would have to be exclusively about staying out of the storm. And since we can't move left and right very well, it'd have to be a vertical game, which saves the trouble of trying to get circles appearing on the board. Green is safe, red is deadly, and yellow is "about to toggle."

So without further ado, here's the world's first, only, and therefore best port of Fortnite for the Atari 2600:

0:00
/0:40

I was going to try for a few more features, but q had other ideas:

It thinks we're done, so we're done

At this point, if Q thinks it's a complete game, who am I to argue?

Overall, Amazon Q Developer gave a solid experience, and there's a lot happening in this space so I'm looking forward to trying a few more things. The free tier definitely made this one more attractive than others, but apparently I have access to a few more with the various subscriptions I've picked up, so I'll give a few more a try. Just maybe not for the 2600.