Inspiration
Extraction shooters put a real decision at the centre of a run: you can always leave, and leaving with less is better than dying with more. I wanted that decision on a phone, in portrait, in ten minutes — and I wanted the gun itself to be the thing you collect.
So the weapon is not picked off a shelf. It is assembled from cards you have found, six slots at a time, and the combination is your build. Two players with the same deck can make guns that play nothing alike.
What it does
A portrait, one-thumb-per-side extraction shooter. You pick a map, build a gun from the cards in your deck, and drop into the scorched wasteland of a hard won alien invasion that raged for years. Inside you gather cards for the next gun and scrap to craft powerups (Amps). Risk going deeper to fight tougher enemies for better loot and extract or die and lose everything you were carrying.
The mechanic I most wanted to test: a fuller bag makes you louder. Noise draws enemies, so the act of getting richer is the act of making the place more dangerous. Greed is the difficulty slider, and the player holds it.
How it was built
Every line of it was written by prompting AI, over many sessions, against a running build.
- One file, no build step. The game is a single HTML file with three.js. It opens from disk, which kept the loop between "change something" and "play it" close to zero.
- A headless test harness. three.js was stubbed so the whole build — renderer included — runs in Node. That is 100 automated checks covering things a browser cannot be asked quickly: whether a level loads and what the loader saw, whether the wall index agrees with a full scan, what a frame costs per system.
- Blender straight into the game. Some of my favourite effects were authored in Geometry Nodes and exported as a mesh plus a JSON of every frame of its shape, so an effect can be built by an artist and run by the game with no code in between. Maps come through the same route, with collection names carrying meaning:
Walls,Roofs,Scatter,Collisionfor placement and custom built geometry node tools utilised to quickly sketch out environments and assets. - A build log kept as we went — over 500 entries recording what was decided and why, including everything that turned out wrong.
Challenges
The hardest problems were not the code. They were the ones where everything reported success and the thing was broken anyway.
A slider carrying a stale default silently overwrote a carefully derived number, so a baseline never reached play. Marker names with a suffix were never matched, because three.js strips dots from node names — Core matched and Cache.001 did not, so the feature looked like it worked. A check asserted on a proxy rather than the outcome and passed while the thing it named was broken. Each of those cost a day, and each produced a new automated check so it could not happen twice.
Turning landscape into portrait was the other one. A phone screen is narrow sideways, and every range in the game had been tuned against a wide window. Measured through the game's own projection, the player could see 179 pixels to the side against enemies that could see 600 — so enemies were opening fire from ground the screen never showed. The fix was not a camera change; it was measuring every distance in the build against the frame and moving the ones that lied.
What was learned
Never trust a green check without knowing what it would have caught. The habit that saved the most time was reintroducing a bug on purpose and watching the test fail before believing it.
Measure, do not reason, about anything with a number in it. Repeatedly the intuition was wrong and the measurement was cheap.
What's next
Each map becomes a different biome with a wreckage as its 'core' its own enemies and its own card pool — a leaking reactor in jungle, a downed mech in a city — with danger and reward both climbing toward the centre. The current demo as 93 unique cards with another 60 that were edited out for the jam.
Built with
three.js, javascript, html5, webgl, glsl, blender, geometry-nodes, gltf, python, node.js, css, canvas, figma, claude, git
Log in or sign up for Devpost to join the conversation.