An example of using Claude Code's /goal to build the same side-scrolling space
shooter in three rendering eras — each one an independent build, each verified by
a deterministic headless playtest.
| Dir | Era | Look |
|---|---|---|
v1-70s-vector/ |
1970s vector / oscilloscope | single-colour line strokes, Asteroids-style |
v2-8bit/ |
1980s/90s 8-bit | colourful pixel sprites, arcade palette |
v3-modern/ |
modern | parallax, particles, glow, screen shake |
Each is its own standalone game with era-appropriate gameplay (not one engine with a swappable skin), and each is verified independently.
| Title | Gameplay |
|---|---|
![]() |
![]() |
| Title | Gameplay |
|---|---|
![]() |
![]() |
| Title | Gameplay (browser) |
|---|---|
![]() |
![]() |
(v3's gameplay shot is captured in a browser, where the HUD renders correctly; the headless playtest renderer stubs text drawing — see "Running a version" below.)
A first attempt at this with /goal produced a game that passed every clause of
the goal and was almost unplayable to look at — a provably-correct game with no
art. The lesson:
A
/goalcondition is a product spec, not just a verification spec. The agent optimises exactly what the condition measures. If the condition only measures "it builds and the levels are completable," that is all you get.
docs/GOAL-PROMPT.md (with docs/PRD.md as the spec) is the corrected approach:
it requires the qualities that make it a real game — distinct enemies, bosses and
weapons, a real difficulty curve, the era's visual identity — expressed as things
a scripted-gameplay playtest can prove, not as adjectives.
Each version builds to a single self-contained index.html. Open it in a browser
to play:
- Arrows / WASD — move
- Space — fire
- P — pause, M — mute, Enter — launch
Headless, deterministic verification:
cd v1-70s-vector && node playtest.mjs # (or v2-8bit / v3-modern)The playtest drives a scripted bot through all five levels via real in-game
controls and prints: per-level COMPLETABLE/FAILED, the invariants
(no-unreachable, no-softlock, boss-difficulty-monotonic, hitreg), a challenge
check (a deliberately naive bot must fail the later levels while a skilled bot
clears them), determinism over three fixed-seed runs, and per-version visual
assertions. Bot-driven screenshots land in each version's shots/ (v3:
screenshots/) directory.
Note: the v3 headless playtest renderer stubs text drawing, so HUD text does not
appear in v3's headless captures (it renders correctly in a browser — see
v3-modern/screenshots/v3-browser-hud.png). The other assertions are unaffected.
A Claude Code session was given the prompt in docs/GOAL-PROMPT.md against the
spec in docs/PRD.md, and used /goal to build and verify each version. The
literal per-version /goal condition strings were derived from the PRD by that
session and are not reproduced here verbatim; the prompt and PRD are the
reproducible artifacts.
Built with Claude Code.





