Last chapter we used an AI to expand a game we already had. This time we go further: we build a brand-new game from an empty screen, with AI as our partner the whole way. It is a vertical space shooter — your ship at the bottom, lasers streaking up, alien ships drifting down to be blasted.
Building from scratch is where an AI assistant is both most useful and most in need of your direction. There is no existing structure to anchor it, so it is easy to let the AI sprawl into a mess you do not understand. The antidote is everything Act 3 taught you: you decide the architecture — the classes and their responsibilities — and the AI fills in the pieces. We will lean hard on that. As always, this is a commentary track, not a line-by-line walkthrough; your shooter will differ from mine, and my version is in the code folder (com.example.vibeshooter) only as one possible outcome.
Code for this chapter: one possible finished version of the Vibe Space Shooter lives in the
Chapter 27folder at github.com/EliteIntegrity/Learning-Kotlin-by-Building-Android-Games. Use it as a reference, not a target.
In this chapter, we will:
- Decide the architecture before writing code, with the AI's help.
- Build the ship, lasers, and aliens as separate classes.
- Wire up firing, spawning, and collisions in the game loop.
- Catch another confident AI mistake.
- Compare results and keep iterating.
Let's build a game from nothing.
What We're Building
The plan, in plain English: a ship sits near the bottom of the screen and slides left and right to follow the player's finger. It fires lasers upward automatically. Alien ships appear at the top and drift down. A laser hitting an alien destroys it and scores a point, with an explosion sound. If an alien reaches the bottom or crashes into the ship, the player loses a life. Three lives, then game over and a tap to restart.
This needs two new sprites — a spaceship and an alienship — and two new sounds, sfx_laser.wav and sfx_explosion.wav. I added the two sprites to our atlas at fresh coordinates and dropped the sounds into res/raw, exactly as Chapter 22 taught. (The full asset list is in this chapter's code folder README.) Lasers I decided to draw as plain rectangles, so they need no art at all. With the assets in place, we open a new project on top of our trusty Chapter 21 engine and start the conversation.
Architecture First
The single most important habit when building something new with an AI is to plan the shape before the code. So my first real prompt is not "write me a space shooter" — that would get a giant, sprawling blob of code I would have to untangle. Instead, I ask the AI to think about structure with me, and I tell it the structure I have in mind:
"I'm building a vertical space shooter in Kotlin on Android, using a custom SurfaceView with a threaded game loop and Canvas drawing — no engine, no Compose, no libraries. Delta-time movement. I want to organize it into small classes, one responsibility each, like this: a
PlayerShip(position, follows touch, draws itself, gives a hit box), aLaser(moves up, draws itself, hit box), anAlien(moves down, draws itself, hit box), and aGameViewthat owns the lists, the firing/spawning timers, collisions, score, and lives. Does that structure make sense for this game? Suggest any changes, but keep it simple — then we'll build it piece by piece."
This does two things. It forces me to articulate the design (which is the real work), and it invites the AI to sanity-check it rather than invent its own. The AI agreed the structure was sound, suggested I might later add a Particle class for explosions (a good idea I noted for later), and — importantly — did not run off and write everything. We had agreed on a blueprint. Now the pieces could be filled in one at a time, each small enough to read in full.
This is the senior-partner mindset from Chapter 25 made concrete. The architecture is mine. The AI is going to do the typing.
Round 1 — The Ship and Its Lasers
I started with the player. My prompt described exactly what I wanted, in terms of the structure we'd agreed:
"Write the
PlayerShipclass. Constructor takes x, y, and size. It draws the 'spaceship' sprite via my Atlas (atlas.draw(canvas, paint, name, left, top, w, h)). Give it amoveTo(targetX, screenWidth)that centers the ship on targetX but keeps it fully on screen, acenterX(), and ahitBox(): RectFinset slightly. Then theLaserclass: constructor takes x (center) and y, travels straight up at 1600 px/sec using delta time, draws as a thin yellow rectangle, hasisOffScreen()andhitBox()."
The AI produced both classes cleanly, in my style, using delta time correctly. I read them, recognized every line as the kind of thing I'd built in Act 3, and accepted them. Then I asked the GameView to tie them together: hold the ship, hold a MutableList<Laser>, move the ship in onTouchEvent toward event.x, and auto-fire a laser every fireInterval seconds using a timer (the spawn-timer pattern from Chapter 15). The AI wired it up, including playing the laser sound on each shot.
I ran it. A ship followed my finger across the bottom, spitting a steady stream of yellow bolts up the screen, each pew firing on cue. Two classes and a few lines of loop, and the player half of the game was done. Reading every piece, I stayed completely clear on how it worked — because the shape was mine and the pieces were small.
Round 2 — Aliens and Collisions
Next, something to shoot. The Alien prompt mirrored the others — a class that drifts down at a random speed, draws the alienship sprite, and offers a hit box. Then the interesting part, collisions:
"In GameView, spawn aliens at random x positions along the top on a timer. Each frame, move every alien down. Then handle three things: if any laser's hit box overlaps an alien (use RectF.intersects), destroy both and add a point and play the explosion sound; if an alien goes past the bottom of the screen, remove it and lose a life; if an alien overlaps the ship's hit box, remove it, lose a life, and play the explosion. Remember to loop backwards when removing from the lists."
Notice I told it to loop backwards — the safe-removal lesson from Chapter 11. I could have let the AI remember, but stating it guaranteed correct code and signaled that I knew what I was doing. The AI produced the nested loop: for each alien (backwards), check it against every laser (backwards) for a hit, then check the bottom edge, then check the ship. It read correctly, and crucially I understood the nested removal, so I could verify it was safe rather than hope it was.
I ran it, and suddenly it was a game. Aliens streamed down, my lasers vaporized them with a satisfying burst of sound, my score climbed, and the occasional alien that slipped through cost me a life. From a blank screen to a playable shooter in two rounds — because the architecture was sound and each piece was small enough to get right.
Catching a Mistake
And, as promised, the AI slipped up — in a way worth seeing, because it is subtle. In its first version of the collision loop, when a laser hit an alien, it removed the alien and then kept checking that same alien against the bottom edge and the ship. Because the alien had just been removed from the list, the follow-up checks read the wrong element — or, in a slightly different version it offered, crashed with an index error. The code looked plausible. It compiled. It even mostly worked. But I had asked for backwards removal precisely because I understood this danger, and reading the loop I could see the missing piece: after destroying an alien, it needed to stop processing that alien and move on. I replied:
"After you destroy an alien from a laser hit, you
continueto the next alien, right? Make sure you don't keep checking an alien you've already removed this frame."
It corrected the loop to continue after a destroy. This is exactly the Chapter 25 lesson in miniature: the AI wrote code that was almost right, with the confidence of code that was completely right, and the only thing standing between "works" and "crashes randomly when a laser and the bottom edge line up" was a reader who understood removal-during-iteration. You are that reader. That is not a small thing — it is the whole thing.
The Result
A couple more refinements — tuning the fire rate so the screen didn't drown in lasers, adjusting alien speed so the game was hard but fair — and the Vibe Space Shooter was complete: ship, lasers, aliens, collisions, score, lives, game over, restart, sound. My version is in the code folder if you want to run it and see one way it can turn out.
But by now you know the refrain. Yours will be different, and better for being yours. Maybe your aliens move in formation, or zig-zag like the wanderers from Chapter 19. Maybe you added the Particle explosions the AI suggested, reusing what you learned last chapter. Maybe your ship fires only when you tap, or has a shield, or the aliens shoot back. Every one of those is a few rounds of the vibe-coding loop away, and every one is something you can build because you understand the foundation it sits on.
What matters is that you built a complete, new game with an AI partner while staying fully in command: you set the architecture, you scoped each feature, you read every line, and you caught the mistakes. That is professional-grade collaboration with AI, and you are doing it.
Over to You
Open a fresh project and build your shooter, or take mine and transform it. Some directions, each a scoped prompt away:
- "Add a
Particleclass and make destroyed aliens burst into sparks, like the explosion in my runner game." - "Make some aliens tougher — they take two laser hits before they're destroyed. Add a
healthto the Alien class." - "Make the difficulty ramp up: aliens spawn faster and move quicker the higher my score gets."
- "Add a
bombspower-up that occasionally drifts down; collecting it clears every alien on screen."
Brief the AI with your constraints, ask for one feature at a time, read the result, run it, refine. And keep the architecture in your head — when a suggestion would muddy your clean little set of classes, reshape it until it fits.
Summary
You built a complete game from an empty screen with AI assistance, and you did it the right way: architecture first. You decided the classes and their responsibilities — PlayerShip, Laser, Alien, and a GameView to orchestrate them — and had the AI fill in each small, readable piece while you checked the work. You wired up firing, spawning, and a backwards-safe collision loop, and you caught the AI making a real, subtle removal-during-iteration mistake that only your own understanding could see. The AI made you fast; your judgment kept it correct.
That is the end of the vibe-coding warm-ups. You have now expanded a game and built one from scratch with AI, and proven you can direct it without losing the wheel. From here, the book turns to its grand finale: a larger, multi-part final project, built with everything you know — your own fundamentals and your AI partner together — into the most ambitious game of the whole book.