Hands-On: Space Invaders & Multi-File Projects
Time to level up — building a more complex game with multiple files, then creating a portfolio homepage that showcases your projects.
The Challenge: Space Invaders
Space Invaders is harder than 2048 because it involves:
- Real-time game loop (60fps rendering)
- Collision detection
- Multiple entity types (player, enemies, bullets)
- State management (lives, score, levels)
- Keyboard input handling (continuous, not one-shot)
This is where we move from vibe coding to a more structured approach.
Project Setup
npm create vite@latest space-invaders -- --template vanilla
cd space-invaders
npm install
npm run dev
Create an AGENTS.md before writing any code:
# AGENTS.md
## Project Overview
Space Invaders game built with vanilla JavaScript and HTML Canvas.
No external game libraries — pure Canvas API.
## Architecture
- `main.js` — Game initialization and loop
- `game.js` — Game state, scoring, level management
- `player.js` — Player ship: movement, shooting
- `enemy.js` — Enemy grid: movement patterns, shooting
- `bullet.js` — Bullet physics and collision detection
- `renderer.js` — All Canvas drawing operations
- `style.css` — Page layout and UI outside canvas
## Code Style
- ES modules with named exports
- Classes for game entities (Player, Enemy, Bullet)
- Constants in UPPER_SNAKE_CASE at top of files
- Game loop uses requestAnimationFrame
The Structured Prompt
Instead of one massive prompt, break it into phases:
Phase 1 — Core engine:
Create the game engine following the architecture in AGENTS.md.
Start with:
1. HTML Canvas element (800x600) centered on page
2. Game loop using requestAnimationFrame at 60fps
3. Player ship at bottom center that moves left/right with arrow keys
4. Shooting with spacebar — bullets move upward
5. FPS counter in the corner for debugging
Don't add enemies yet — just the player, movement, and shooting.
Phase 2 — Enemies:
Add the enemy grid:
1. 5 rows of 11 enemies, arranged in a grid
2. Enemies move horizontally, then drop down when hitting edges
3. Enemies speed up as fewer remain
4. Collision detection: player bullets destroy enemies
5. Score: +10 per enemy destroyed, displayed on screen
Phase 3 — Complete game:
Add remaining game features:
1. Enemy shooting — random enemies fire downward at intervals
2. Player has 3 lives — loses one when hit by enemy bullet
3. Game over when lives reach 0 or enemies reach player row
4. Win condition: all enemies destroyed → next level (faster enemies)
5. Start screen with "Press ENTER to play"
6. Game over screen with final score and "Press ENTER to restart"
Why Multi-File Matters
Single-file games work for 2048 (~200 lines). Space Invaders will be 500+ lines.
Problems with single-file games:
- AI loses track of logic in large files
- Can't modify one system without risking others
- No reusable components
- Hard to debug
Benefits of multi-file architecture:
- Each file is small enough for AI to fully understand
- Change collision logic without touching rendering
- Test systems independently
- AI can focus on one file at a time
When working with multi-file projects, tell the AI which file to modify:
In enemy.js, change the enemy movement pattern from linear
to sinusoidal — enemies should wave left and right as they
move down the screen.
Building a Portfolio Homepage
Now let's create a homepage that showcases your 2048 and Space Invaders games:
npm create vite@latest my-portfolio -- --template vanilla
cd my-portfolio
npm install
The prompt:
Build a portfolio homepage with the following:
1. Hero section with my name and "AI-Assisted Developer" tagline
2. Project cards section with two cards:
- "2048" — sliding puzzle game, link to /games/2048/
- "Space Invaders" — classic arcade game, link to /games/space-invaders/
3. Each card has: screenshot placeholder, title, description, "Play" button
4. About section explaining this was built using AI coding tools
5. Footer with links to GitHub
Design:
- Dark theme with gradient accents
- Modern sans-serif font (system font stack)
- Responsive — looks good on mobile and desktop
- Smooth scroll between sections
- Subtle hover animations on project cards
Embedding the Games
To make the games playable from the portfolio:
Add the built versions of my games to the portfolio:
1. Create a public/games/ directory
2. Copy the 2048 build output to public/games/2048/
3. Copy the Space Invaders build to public/games/space-invaders/
4. Make the "Play" buttons on the portfolio link to these paths
5. Add a "Back to Portfolio" link inside each game page
Build the games first:
cd ../game-2048 && npm run build
cd ../space-invaders && npm run build
Then copy the dist/ output from each game into my-portfolio/public/games/.
Multi-Project Workflow
Working across multiple projects teaches critical AI skills:
Context switching:
- When you move between projects, the AI loses context
- Always re-orient: "I'm now working on the portfolio project, which is in /my-portfolio"
- Or use separate terminal sessions per project
Cross-project references:
- "Style the portfolio cards the same way the 2048 game tiles are styled"
- The AI can match patterns across projects if you describe them
Dependency management:
- Each project has its own
package.jsonandnode_modules - Don't share dependencies between projects
- The portfolio is independent — it just hosts the built game files
Key takeaway: Real development involves multiple interconnected projects. Practice managing context and cross-references now.
Lessons from Complex Projects
What changes as projects get bigger:
| Simple (2048) | Complex (Space Invaders + Portfolio) |
|---|---|
| One prompt | Multiple phased prompts |
| Single file | Multi-file architecture |
| No AGENTS.md needed | AGENTS.md is essential |
| Vibe coding works | Spec-driven approach required |
| Minutes to build | Hours to build |
| Easy to verify | Need testing strategy |
The golden rule: As complexity grows, invest more in upfront planning and less in hoping the AI gets it right on the first try.
---quiz question: Why is a multi-file architecture important for complex AI-assisted projects? options:
- { text: "It makes the project look more professional", correct: false }
- { text: "Each file is small enough for the AI to fully understand, and systems can be modified independently", correct: true }
- { text: "AI tools require separate files to function", correct: false } feedback: With multi-file architecture, the AI can focus on one manageable file at a time, reducing the chance of errors. You can also modify one system (like collision detection) without risking changes to another (like rendering).
---quiz question: Why should you break a complex project prompt into phases instead of one massive prompt? options:
- { text: "To use fewer API tokens", correct: false }
- { text: "Each phase can be verified before building on it, catching issues early", correct: true }
- { text: "AI models can only process 10 lines at a time", correct: false } feedback: Phased development lets you verify each component works before adding complexity. If the game loop is broken, there's no point in adding enemies. This approach catches issues early and makes debugging easier.