🌈 ESP32-S3 Rainbow: ZX Spectrum Emulator Board! Get it on Crowd Supply →
View All Posts
read
Want to keep up to date with the latest posts and videos? Subscribe to the newsletter
HELP SUPPORT MY WORK: If you're feeling flush then please stop by Patreon Or you can make a one off donation via ko-fi

Fresh from resurrecting Tanks! Mayhem, I went digging for the other game I wrote back in the early App Store days: Invaders!, a 2009 Space Invaders homage for the iPhone. It wasn’t a straight clone - the aliens teleport in, some of them carry bubble shields, power-ups drift down on parachutes, and the score is displayed on glowing nixie tubes, because in 2009 I apparently thought everything looked better as a nixie tube.

The code that wasn’t there

There was one problem: I couldn’t find the source code anywhere. Tanks had been sitting safely in Dropbox for sixteen years. Invaders was on none of my drives, none of my backups, nowhere. It was written two laptops and at least three backup strategies ago, and I’d quietly written it off as gone forever.

Then I remembered that before GitHub ate the world, there was Bitbucket. I managed to log back into an account I’d forgotten I had, and there it was: the Objective-C, the sprite sheets, the Photoshop files, the .caf sound effects, even the original App Store screenshots. A complete time capsule from 2009.

I got lucky with one detail: Bitbucket deleted every Mercurial repository on the platform back in 2020. If nine-years-younger me had picked hg instead of git, this post wouldn’t exist.

The port

Same trick as last time: point Claude Code at the folder and ask it to get the game running in the browser. It read through the Objective-C classes, mapped out the sprite sheet, converted the .caf sounds to WAV with afconvert, and produced a plain JavaScript canvas game with no build step.

Invaders! running in the browser

Play it now at invaders.atomic14.com. Arrow keys or A/D to move, space to fire, 1-5 to toggle power-ups once you’ve caught them. It works on phones too, with the original touch controls.

And here’s the 2009 original for comparison:

The 2009 original

The clever bit of the port is the coordinate system. The original game logic all runs in OpenGL coordinates - origin at the bottom left, y pointing up. Rather than translating every constant and every bit of movement code to the browser’s upside-down coordinate system (and inevitably introducing a hundred off-by-one bugs), the web version keeps all the game logic in the original coordinates and flips everything in one place, at draw time. That meant the numbers from the 2009 code - the barrier positions, the alien grid spacing, the bullet speeds, the difficulty curve - could be copied across verbatim.

So what you’re playing is genuinely the 2009 game: the same 8x4 grid of aliens that speeds up as you thin it out, the same bubble-shielded aliens that start appearing from level 2 (that’s level 3 in the screenshot above), the same barriers that erode column by column (invader fire chews the top, your own shots chew the bottom), the same UFO trundling across every ten seconds.

A seventeen-year-old bug

The power-up system had a surprise in it. Each power-up is supposed to be gated by level - you shouldn’t see the laser blast until you’re a few levels in. Here’s Claude’s explanation of what the original code actually does:

The loop walks through the candidate upgrades looking for one that’s unlocked at the current level. But if none of them pass the check, it falls out of the loop with the last candidate still sitting in the upgrade variable - and then grants it anyway. The level gate compiles, runs, and has never once stopped a power-up from dropping.

Seventeen years that bug has been in the game, and neither I nor any player ever noticed, because the effect is just “you sometimes get a good power-up early”, which nobody complains about. The web version filters the candidates properly. It’s possible I’ve made the game slightly worse by fixing it.

The font that can’t say “dash”

One small improvement over the original: when you catch a power-up, the game now tells you what you got and which key fires it, in text along the bottom of the screen. The original just played a sound and lit up an icon, and you were left to work out what the mysterious fifth button did mid-firefight.

The text is drawn with the original 2009 bitmap font, which led to a very 2009 problem: the first version of the message said “Rapid fire - press 5”, and rendered with a hole in the middle. The font atlas contains the characters I needed in 2009 and not one glyph more: letters, digits, a period. No dash. No colon. Rather than regenerate a texture that’s been pixel-perfect for seventeen years, the message now reads “Rapid fire. Press 5”. The font wins.

Game over - you'll see this a lot

The code is on GitHub at atomic14/invaders-web: plain JavaScript, one file of game logic, every constant traceable back to the Objective-C it came from. The original source is in the repo too, safely somewhere that isn’t a forgotten Bitbucket account.

Two games rescued in one week. I’m starting to wonder what else I’ve written off as lost.

Related Posts

Tanks! Mayhem is back: 16 years later, in your browser - In 2010 I wrote a Battlezone-style tank game with glowing vector graphics to learn OpenGL ES 2.0. In 2011 Atari had it pulled from the US App Store. The source has been sitting in Dropbox ever since. This week I pointed Claude Code at it and got the whole single-player game ported to JavaScript and WebGL in an afternoon. It's live at tanks.atomic14.com. This post covers the resurrection: how the neon glow effect actually works (it's not a bloom pass), the left-handed rotation bug that put the camera inside the gun barrel, and the radar shader that shipped sixteen years late.
I learned to solve a Rubik's cube and it was incredibly disappointing - I tried to learn the Rubik’s cube and got bored of rote algorithms, which nudged me toward a GPS-to-map analogy that mirrors the junior-to-senior engineer journey: from following instructions, to pattern matching, to real understanding. Coding agents crush the first two levels, but they still lack taste and judgment—the difference between code that works and code that works well. I may never be a speed cuber, but with agents, I might just become a speed coder.
Vibing a PCB - surprisingly good - In my latest adventure, I challenged AI to design a working ESP32-S3 development board from scratch using Atopile and Claude. The idea was as simple as vibe-coding actual hardware without diving into the code. It was a chaotic yet fascinating journey, with some misses like unwired components and a forgotten capacitor. After a few prompts, the AI delivered a surprisingly functional board featuring USB-C, an AMS1117 regulator, and status LEDs. While not yet perfect, vibe-coding feels like a glimpse into the future of hardware design.
Creating an OpenGL game for both the Palm and iOS - I've made a triumphant return to the blogosphere with the release of my new game, 'Tanks!' developed for Palm Pre/Pixie and soon for iPhone devices. The game, an experiment to learn OpenGLES 2.0, is a testament to the feasibility of porting C++ or C code from iOS to Palm PDK, despite minor challenges with UI interaction and audio. So gear up, folks! Download 'Tanks!', step onto the battlefield and let the mayhem begin! Next stop on my coding odyssey - Android!
HELP SUPPORT MY WORK: If you're feeling flush then please stop by Patreon Or you can make a one off donation via ko-fi
Want to keep up to date with the latest posts and videos? Subscribe to the newsletter
Blog Logo

Chris Greening


Published

> Image

atomic14

A collection of slightly mad projects, instructive/educational videos, and generally interesting stuff. Building projects around the Arduino and ESP32 platforms - we'll be exploring AI, Computer Vision, Audio, 3D Printing - it may get a bit eclectic...

View All Posts