Skip to content
ISSUE #51 May 22, 2026 10 MIN READ

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.

VS Code file explorer showing a clean repo with only .codex/skills containing webg-spec-to-goal and playwright-cli folders, beside a Codex 0.138.0 terminal session with gpt-5.5 xhigh model pointed at ~/Dev/raiden-shooter
Codex terminal showing the $webg-spec-to-goal skill invocation with the plain-English game description typed into the composer — gpt-5.5 xhigh model, 0% context used

.

.

.

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 LayerWhat it builds
00FoundationVerify scaffold boots, state bridge works
01Core MechanicThe thing that makes this game this game (shooting)
02ContentOpposition (enemies)
03–04Progression + SystemsScoring, health, HUD
05–06DepthWaves, difficulty
07PolishArt, 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.

Codex output showing the webg-spec-to-goal skill running pwd, rg --files, and ls -la to explore the empty repo before asking any scoping questions
Codex presenting 5 scoping decisions with recommended defaults — name/slug, genre detection (shoot-em-up), scope (player ship, bullets, enemies, health, score), mechanics (single weapon, no boss, no power-ups), and audio (include in later polish goal) — with the user replying "Go with your recommendations"

.

.

.

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 plangoals-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:

#GoalTimeTests
00Foundation7m 40s3
01Player Ship6m 17s9
02Player Weapons6m 06s14
03Enemies8m 57s19
04Scoring & Health8m 54s24
05HUD6m 22s29
06Wave System7m 16s34
07Polish26m 32s39

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.

Codex output showing the skill reading scaffold and goal templates, confirming the Phaser 3 + Vite + Arcade Physics + state bridge + Playwright scaffold, and beginning to write files
Split view — left: VS Code file explorer showing the full scaffolded structure with goals/00-foundation through 07-polish, src/, tests/, public/. Right: Codex completion summary listing all created files, verification results (npm install, npm run typecheck passed, npm test 3/3 boot tests passed), and the dev server running at http://127.0.0.1:8080

.

.

.

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 terminal showing the /goal command for 00-foundation pasted into the composer, ready to execute

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.

Goal 00 completion summary showing changed files (constants.ts, MenuScene.ts, helpers.ts, boot.spec.ts, PROGRESS.md), verification results (npx tsc --noEmit, Playwright tests, npm test), screenshot artifacts (menu.png, game-scene.png), and final time of 7m 40s

.

.

.

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 03 completion showing pooled enemies, timed spawning, downward movement, bullet-enemy overlap destruction, offscreen recycling, enemy state bridge reporting — 19/19 tests passed, including full regression, in 8m 57s

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.

Goal 06 completion showing data-driven WaveSystem.ts, wave configuration in waves.ts, win-state implementation, 5 new tests plus full 34-test regression — all passed. Screenshots captured. 7m 16s

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.

Codex terminal showing the /goal command for 07-polish pasted into the composer

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.

Goal 07 completion showing pixel art assets generated, WAV sound and music integrated, BootScene loading, parallax stars, particles, camera shake, FeedbackSystem wiring, state bridge fields unchanged, 39/39 tests passed including full regression, with the audio balance caveat noted. 26m 32s

.

.

.

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:

PostDomainGoalsAutonomous timeTests
1WordPress plugin128 minbrowser checks
2CLI tool280 min35
3Browser game878 min39

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:

  1. Add new goal slices — power-ups, boss fights, more enemy types, weapon upgrades, difficulty tuning.
  2. Improve the webg-spec-to-goal skill 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.

Nathan Onn

Freelance web developer. Since 2012 he’s built WordPress plugins, internal tools, and AI-powered apps. He writes The Art of Vibe Coding, a practical newsletter that helps indie builders ship faster with AI—calmly.

Join the Conversation

Leave a Comment

Your email address will not be published. Required fields are marked with an asterisk (*).

Enjoyed this post? Get similar insights weekly.