How I Used 8 Codex /goal Runs to Build a Browser Game From Scratch
One paragraph describing a game idea.
Eight /goal commands. Seventy-eight minutes of autonomous Codex time.
A playable vertical shooter in the browser.
The WordPress plugin post was one goal, 28 minutes. The CLI tool post was two goals, 80 minutes. This time: eight goals, ~78 minutes of autonomous Codex time, and the output is something you can play with a keyboard.
Here’s the paragraph that started it:
Build me a Raiden-type vertical shooter web game. The player ship is at the bottom of the screen, enemies come down from the top, and the player shoots bullets upward to destroy them. Standard 800×600 resolution. Use pixel art style.
That paragraph took three tries.
My first version was “make me a fun shooter game” — too vague for a skill that needs to generate 8 goals from it. The final version named the genre, the perspective, the resolution, and the art style.
Four sentences. Five minutes of thinking to save 78 minutes of supervision. What came out the other end is Ion Viper — a Phaser 3 game with player movement, shooting, pooled enemies, wave progression, scoring, health, a HUD, pixel art, particles, screen shake, and sound effects.
The honest caveat, same as always: the codex goal command produced the code, but the spec produced the outcome. This time the spec wasn’t a single goal trio — it was eight of them, generated all at once by a skill that understands how games decompose.
If you’re new to the series, the WordPress plugin post covers what /goal is, the goal trio (GOAL.md, VERIFY.md, PROGRESS.md), and the continuation prompt.
This post assumes you’ve read at least one of the previous two.


.
.
.
Meet webg-spec-to-goal — The Skill That Generates Every Goal at Once
The WordPress plugin post introduced wp-spec-to-goal, a Codex Agent skill that turns a paragraph into the goal trio. That skill produced one goal.
The CLI tool post introduced cli-spec-to-goal, which detected the project needed splitting and generated one goal at a time — with a plan for the rest.
webg-spec-to-goal generates ALL goals in a single pass. All three skills from this series are open source at github.com/nathanonn/agent-skills.
Why?
Because games have a predictable build order that the skill can exploit:
| # | Goal Layer | What it builds |
|---|---|---|
| 00 | Foundation | Verify scaffold boots, state bridge works |
| 01 | Core Mechanic | The thing that makes this game this game (shooting) |
| 02 | Content | Opposition (enemies) |
| 03–04 | Progression + Systems | Scoring, health, HUD |
| 05–06 | Depth | Waves, difficulty |
| 07 | Polish | Art, sound, particles, juice |
The skill inspects the game description, auto-detects the genre (shoot-em-up, card game, platformer, tower defense, puzzle), tailors the goal decomposition to that genre, and writes everything — the scaffold, the plan, and all 8 goal trios.
One concept needs explanation: the state bridge.
Every goal adds typed fields to window.__GAME_STATE__, and Playwright tests read that object to verify game behavior without screenshot pixel comparison. Goal 00 adds scene and ready. Goal 01 adds playerPosition and playerAlive. By Goal 06, the state bridge carries 13 fields. Verification tests assert against these fields — meaning an automated test can confirm “the player is alive and at position (400, 500)” without trying to parse pixels from a rendered canvas.
That’s what makes automated testing possible for a visual, interactive medium.
From the prompt, the skill detected “shoot-em-up” and proposed defaults:
- name/slug (
raiden-shooter, matching the repo name), - resolution (800×600),
- mechanics (single weapon, no boss, no power-ups for a tight MVP),
- and art style (pixel art with a later polish goal for audio).
I confirmed with “Go with your recommendations.”
Phaser domain knowledge also lands in AGENTS.md — scene lifecycle, object pooling, delta-time movement, state initialization in init() instead of constructors — so Codex has it available during every /goal run.


.
.
.
The Scaffold and the Plan
The skill writes two things.
The scaffold is a runnable Phaser 3 project — TypeScript, Vite, Playwright, scene shells, state bridge — that boots at localhost:8080 and passes 3 tests out of the box.
The plan — goals-plan.md — maps all 8 goals in sequence with dependencies, acceptance criteria, and the state bridge growth table.
Here’s what the skill produced — and what each goal actually took:
| # | Goal | Time | Tests |
|---|---|---|---|
| 00 | Foundation | 7m 40s | 3 |
| 01 | Player Ship | 6m 17s | 9 |
| 02 | Player Weapons | 6m 06s | 14 |
| 03 | Enemies | 8m 57s | 19 |
| 04 | Scoring & Health | 8m 54s | 24 |
| 05 | HUD | 6m 22s | 29 |
| 06 | Wave System | 7m 16s | 34 |
| 07 | Polish | 26m 32s | 39 |
Those are the real numbers from the actual run.
The test count column tells a story on its own. Each goal adds its own Playwright tests AND runs all previous ones. By Goal 06, the 34-test regression suite covers every system built so far. The “fields accumulate, never remove” rule in the state bridge contract is what keeps those regressions honest.


.
.
.
Goal 00: Foundation — The Sanity Check
The /goal command is identical in shape to the WP and CLI versions:
/goal Complete goals/00-foundation/GOAL.md. Use goals/00-foundation/VERIFY.md
as the verification contract. Update goals/00-foundation/PROGRESS.md continuously.
Treat uncertainty as incomplete.
Paste. Press enter. Walk away.

Codex customized the constants, wired the menu-to-game transition, set up the state bridge base fields, and wrote Playwright tests covering canvas size, console errors, and scene transitions.
7 minutes and 40 seconds. 3 tests passing. Menu screen rendering.
A lightweight sanity check — confirm the scaffold actually works before building on top of it. Every game starts here.

.
.
.
Goals 01–06: The Assembly Line
Six goals, each one building on the last, each one autonomous, each one inheriting the full codebase state from the run before it.
Goal 01 — Player Ship (6m 17s): Player sprite at bottom-center, WASD and arrow keys, clamped to bounds. 9 tests.
Goal 02 — Player Weapons (6m 06s): SPACE fires pooled bullets upward with fire-rate limiting. 14 tests.
Goal 03 — Enemies (8m 57s): Enemies spawn from the top, move downward, and are destroyed by bullet overlap. 19 tests. This is the moment the game becomes a game — something that absorbs your shots and shoots back.

Goal 04 — Scoring & Health (8m 54s): Score on kill, health on contact, invulnerability frames, game over on death. 24 tests.
Goal 05 — HUD (6m 22s): Parallel HUD scene showing score, health, and wave number without blocking gameplay input. 29 tests.
Goal 06 — Wave System (7m 16s): Data-driven waves replace endless spawns. Difficulty escalates. Clearing the final wave triggers a win state. 34 tests.

Here’s what makes the assembly line work:
Each codex goal command run starts by reading the entire codebase that previous goals built. Codex understands the existing scene structure, the existing test patterns, the existing state bridge fields. Goal 06 extends what Goals 00 through 05 established — it doesn’t start from scratch.
Somewhere around Goal 05…
Pasting the /goal command stopped feeling like an experiment and started feeling like filling out a form. Copy the command, swap the folder name, press enter. The novelty was gone by the HUD goal. That’s the point — when the eighth paste feels boring, the pattern has landed.
And the test regression discipline kept compounding.
Goal 06 runs 34 tests — 5 new ones for the wave system plus all 29 inherited from previous goals.
Nothing broke.
That’s the state bridge contract at work: fields accumulate, never get removed, and every prior test still finds what it expects.
.
.
.
Goal 07: Polish — Where the Game Comes Alive
The final goal is the longest — 26 minutes and 32 seconds — and the most visually dramatic. Placeholder rectangles become pixel art. Silence becomes sound.

What Codex did in this goal:
- Generated pixel art assets using
$imagegen— player ship, enemy drone, bullets, explosion particles, space background, parallax stars — all following the magenta chromakey pipeline documented in AGENTS.md. - Created sound effects (fire, hit, explosion, player damage) and background music.
- Built a
FeedbackSystem: particle emitters on enemy destruction, camera shake on player damage. - Added parallax scrolling background with a tiling star layer.
- Polished MenuScene and GameOverScene presentation.
- Ran all 39 tests — 5 new polish tests plus the full 34-test regression. All green.
One honest limitation Codex flagged: it can verify that audio assets load and trigger correctly, but whether they actually sound good is a human judgment.
26 minutes and 32 seconds. More than three times the average of the other seven goals.
Polish is where the token budget earns its keep — art generation, audio integration, particle tuning, and full regression across the entire test suite.

.
.
.
Does It Actually Work?
Same instinct as the previous two posts: close the terminal and test it like a real player.
The first time I opened localhost:8080 after Goal 07 finished, I expected colored rectangles with sound effects layered on top. Pixel art loaded instead — a ship, a background with parallax stars, enemies with actual sprites. The gap between what I typed into the composer and what appeared in the browser was wider than any of the previous posts.
Open the browser. Menu screen with the game title. Press SPACE.
Player ship at the bottom, pixel art sprites, parallax background scrolling. Enemies descend in waves. Bullets fire upward with sound effects. Enemies explode with particles and a satisfying pop. Get hit — screen shakes, health drops, the ship flashes with invulnerability frames. Clear all waves — win state. Die — game over screen with the final score and a prompt to restart.
Here’s the gameplay:
What’s there: movement, shooting, enemies, waves, scoring, health, HUD, pixel art, sound, music, particles, screen shake. All built by Codex across 8 autonomous runs.
What’s not there: power-ups, boss fights, multiple enemy types beyond the basic drone, weapon upgrades, mobile controls.
The game is playable.
It’s fun for about 90 seconds.
It delivers exactly what the spec asked for.
(You’ll notice some screenshots show “Raiden Shooter” in file paths and title screens — that was the working name during development. The published game is Ion Viper.)
.
.
.
The Numbers
Concrete summary of the build:
- Skill invocation: 1 (generated all 8 goals at once)
- Goal runs: 8
- Total autonomous time: ~78 minutes across all goals
- Total human input: one paragraph + “Go with your recommendations”
- Source files: 18 TypeScript files across scenes, objects, systems, and configs
- Test files: 8 Playwright spec files
- Tests: 39 (all passing)
- Assets: 9 image files, 5 audio files
- Lines of game code: 1,463
Series comparison:
| Post | Domain | Goals | Autonomous time | Tests |
|---|---|---|---|---|
| 1 | WordPress plugin | 1 | 28 min | browser checks |
| 2 | CLI tool | 2 | 80 min | 35 |
| 3 | Browser game | 8 | 78 min | 39 |
The trend: more goals, same pattern, roughly the same time per goal (~7–10 minutes each, except polish at 26 minutes).
.
.
.
What’s Left (And Why That’s the Point)
The game is complete as specified. All 8 goals passed. All 39 tests are green. Every verification contract is satisfied.
And it’s clearly not done.
No power-ups. No boss fights. One enemy type. No weapon upgrades. Three waves. No difficulty curve beyond wave configuration. No mobile controls. No deployment.
This is intentional.
The MVP proves the pattern works for games.
The next post (Part 2) will:
- Add new goal slices — power-ups, boss fights, more enemy types, weapon upgrades, difficulty tuning.
- Improve the
webg-spec-to-goalskill based on what we learned.
The split mirrors how real game development works.
You build the core loop, validate it, then layer features on top. Goal chaining makes that natural — each new slice inherits the full state of what was built before.
If you want to play with it now, the repo is public at github.com/nathanonn/ion-viper. Clone it, run npm install && npm run dev, open localhost:8080, and shoot some drones.
Part 2 is where it gets interesting.
.
.
.
The Bigger Picture
Three posts, three domains, one pattern.
The codex goal command works the same way whether you’re building a WordPress plugin, a CLI tool, or a browser game. Skill generates spec, /goal executes spec, PROGRESS.md proves it.
The skill is the variable.
wp-spec-to-goal knows WordPress hooks and wp-env. cli-spec-to-goal knows Commander.js and exit codes. webg-spec-to-goal knows Phaser scenes, object pooling, and the state bridge pattern. Domain knowledge lives in the skill. The execution loop stays the same.
What scales: each new skill is a one-time investment.
Build webg-spec-to-goal once, use it for every Phaser game from now on. Five minutes turning a paragraph into 8 goals — the same investment whether you’re building your first game or your tenth.
What changed from March — when the Reddit summarizer needed six supervised steps — to now, when the same kind of project needs one skill invocation and a paste.
Your job is still writing the plan. The plan just got more structured.

Leave a Comment