oneshotlm
Compare all models on this prompt →

Space Invaders · gemma-4-26b-a4b-it

Build a playable Space Invaders game on a canvas: a player cannon that moves and shoots, a descending grid of aliens that advance and fire back, destructible bunkers, score, and lives. Procedural graphics only, no external assets.

⛨ sandboxed Open in new tab ↗
transcript · 8 messages
user

Build a playable Space Invaders game on a canvas: a player cannon that moves and shoots, a descending grid of aliens that advance and fire back, destructible bunkers, score, and lives. Procedural graphics only, no external assets.

assistant
thinking
The user wants a complete, playable Space Invaders game in a single `index.html` file.
It must include:
- Player cannon (movement and shooting).
- Descending grid of aliens (moving, advancing, firing back).
- Destructible bunkers.
- Score.
- Lives.
- Procedural graphics (Canvas API).
- No external resources/CDNs/network requests.

Plan:
1.  Set up the HTML structure with a `<canvas>` element and basic CSS for layout.
2.  Implement the game engine:
    *   Game Loop (requestAnimationFrame).
    *   Input handling (Keyboard: Left, Right, Space).
    *   Entity classes/objects: Player, Bullet, Alien, AlienBullet, Bunker, Particle (for explosions).
    *   Collision detection (AABB).
    *   Game state management (Start, Playing, Game Over, Win).
    *   Drawing functions (Procedural shapes for everything).

Game Mechanics Details:
- Player: Moves horizontally. Can shoot one bullet at a time (or maybe a few, but classic is one).
- Aliens: Grid of aliens. Move horizontally, hit edge -> descend and reverse direction. Speed increases as fewer aliens remain.
- Aliens fire: Randomly select an alien to fire a bullet down.
- Bunkers: Destructible blocks. When a bullet hits, it removes a pixel/block.
- Score: Points for aliens, extra for top row/special.
- Lives: Start with 3. Lose one if alien bullet hits player or alien reaches bottom.

Graphics:
- Player: Simple shape (rectangle/trapezoid).
- Aliens: Pixel-art style shapes drawn with rectangles.
- Bunkers: Series of small squares.
- Background: Dark space with some stars (drawn once or as static).

Let's start coding.
write index.html (18238 bytes)
toolResult

Successfully wrote 18238 bytes to index.html

assistant
thinking
The user wants a playable Space Invaders game. I have written the `index.html` file. Let me quickly check the code for any obvious errors or improvements.

The code has:
- Player with movement and shooting.
- Aliens with movement, direction reversal, and shooting.
- Bunkers that are destructible.
- Score and Lives.
- Particle effects for explosions.
- Game states: START, PLAYING, GAMEOVER, WIN.

One potential issue: the `alienDir` and `alienSpeed` were defined outside `initGame` but the `initGame` function resets `score` and `lives` but not `alienDir` and `alienSpeed`? Wait, `initGame` is called when restarting from `GAMEOVER`.

In `initGame`:
```javascript
        function initGame() {
            score = 0;
            lives = 3;
            gameState = 'PLAYING';
            player = new Player();
            aliens = [];
            playerBullets = [];
            alienBullets = [];
            particles = [];
            
            // Create Aliens
            for (let row = 0; row < ALIEN_ROWS; row++) {
                for (let col = 0; col < ALIEN_COLS; col++) {
                    const x = col * (ALIEN_WIDTH + ALIEN_PADDING) + 50;
                    const y = row * (ALIEN_HEIGHT + ALIEN_PADDING) + 50;
                    aliens.push(new Alien(x, y, row % 3));
                }
            }

            // Create Bunkers
            bunkers = [];
            const bunkerSpacing = WIDTH / (BUNKER_COUNT + 1);
            for (let i = 0; i < BUNKER_COUNT; i++) {
                bunkers.push(new Bunker(bunkerSpacing * (i + 1) - BUNKER_WIDTH/2, HEIGHT - 150));
            }
        }
```
It doesn't reset `alienDir` and `alienSpeed`. I should probably add those to `initGame`.

Also, the `WIN` state handling in the event listener is a bit redundant with `initGame`. Let's clean that up.

And I should make sure `alienDir` and `alienSpeed` are reset in `initGame`.

Let's refine the `initGame` and the keyboard event listener.

I'll also add a small feature: increasing difficulty with levels.

Wait, I see a potential bug:
```javascript
            if (reachedEdge) {
                alienDir *= -1;
                aliens.forEach(a => {
                    a.y += 20;
                    if (a.y + a.h > player.y) {
                        gameState = 'GAMEOVER';
                    }
                });
            }
```
If `reachedEdge` is true, it moves ALL aliens down. This is correct for Space Invaders.

Let's improve `initGame` and the `keydown` listener.

I will also add a little bit more "juice" to the alien movement - making them speed up as they are destroyed. I already have `alienSpeed += 0.05;` in the collision detection, but it should probably be reset on `initGame`.

Revised plan for `index.html`:
1. Move `alienDir` and `alienSpeed` into `initGame`.
2. Simplify the `keydown` handler.
3. Ensure everything is properly reset.

Actually, I'll just rewrite the script section to be cleaner.
edit {}
toolResult

Validation failed for tool "edit": - path: must have required properties path, edits Received arguments: {}

assistant
thinking
Ah, I forgot to provide the `edits` argument. I will rewrite the `index.html` file with the improvements.
write index.html (14722 bytes)
toolResult

Successfully wrote 14722 bytes to index.html

assistant
thinking
The game is ready. It meets all the requirements:
- Single file `index.html`.
- CSS in `<style>`, JS in `<script>`.
- No external resources.
- Player cannon with movement and shooting.
- Descending grid of aliens that move and fire back.
- Destructible bunkers.
- Score, lives, levels.
- Procedural graphics using Canvas.

I'll do a final check of the code.
- `initGame(isNewLevel)` handles both starting fresh and starting a new level.
- `alienDir` and `alienSpeed` are reset correctly.
- `playerBullets` and `alienBullets` are cleared.
- `gameState` transitions are handled.
- `checkPointRect` is used for collision detection.
- `spawnExplosion` creates particles.

The `initGame(true)` call in the `WIN` state will correctly increment the level and set up the next stage.

One small thing: `alienSpeed` is set to `1 + (level * 0.2)` in `initGame`. This is good.
The `alienSpeed += 0.05` in collision detection makes it harder as aliens are killed.

The game looks solid.

The Space Invaders game has been built as a single-page, self-contained web application. It features: - **Player Control**: Move left/right with arrow keys and shoot with the Space bar. - **Alien AI**: A grid of aliens that descends and moves faster as their numbers dwindle, occasionally firing back. - **Destructible Bunkers**: Protective bunkers that can be chipped away by both player and alien projectiles. - **Game Progression**: Score tracking, lives, and multiple levels with increasing difficulty. - **Procedural Graphics**: Entirely rendered using the HTML5 Canvas API with no external assets or network requests. - **Visual Effects**: Particle-based explosions for destroyed entities. You can run the game by opening the `index.html` file in any modern web browser. ```html <!-- index.html (Self-contained) --> <!DOCTYPE html> <html lang="en"> ... (as implemented above) ``` index.html is present.

TAKE IT TO CODE

A single self-contained HTML file — copy it and open in any browser, or reuse the prompt with your own pi-agent run.

RUN

modelgemma-4-26b-a4b-it
vendorGoogle
harnesspi-agent
generated2026-07-22

EVALUATION

4/5 working

Space Invaders with title screen, colorful alien grid, bunkers, score/lives HUD; responds to keyboard, aliens moved and bunkers eroded.

Vision grade · anthropic/claude-sonnet-5

MEASUREMENTS

Raw readings from the capture, not a verdict — the grade above is the only judgement. Percentages are how much of the screen changed; the measure under-reports sparse motion on a dark background.

idle motion0.0%
on click0.0%
on drag0.0%
on wheel0.0%
on enter + space7.4%
on arrow keys6.1%
on w/a/s/d8.2%
frame spread24.5 / 255
console errors0
js errors none

METRICS

runtime163.6s
tokens in11k
tokens out15k
cached17k
cost / run$0.0056