Skip to content

Latest commit

 

History

History
185 lines (141 loc) · 12.7 KB

File metadata and controls

185 lines (141 loc) · 12.7 KB

Phaser

boringstack.xyz GitHub Play the demo

CI CodeQL OpenSSF Scorecard MIT Phaser 4 TypeScript 6 Bun

Phaser + TypeScript, AI-first.
A BoringStack template.

boringstack tsforge eslint-plugins

A reusable, strictly-typed Phaser 4 starter so AI agents can ship at high velocity without eroding structure — and so a programmer who has never shipped a game can become a one-person studio in a weekend.

This repo is part of boringstack-xyz. Sister projects: the BoringStack fullstack template, tsforge (the TypeScript build harness), and eslint-plugins.

Backend engineer, tech lead, web developer who always wanted to make games? Start with docs/learn/ — a 2.5-hour primer that bridges "I can write code" to "I can generate art, design a core loop, and ship on itch.io."

Start a new game with tsforge (/scaffoldPhaser, or tsforge scaffold --archetype phaser --dest ./my-game), or click "Use this template" on GitHub. Then read BUILD_THE_GAME.md.

After forking: one-time repo setup

  1. Enable GitHub PagesSettings → Pages → Build and deployment → Source: "GitHub Actions". Without this the deploy-pages workflow 404s on the first run. The org demo is served at phaser.boringstack.xyz (Chrome treats boringstack-xyz.github.io as a lookalike of boringstack.xyz). Forks keep the default https://<user>.github.io/<repo>/ URL.
  2. Allow Actions to open PRs (so release-please can cut release PRs) — Settings → Actions → General → Workflow permissions → [x] Allow GitHub Actions to create and approve pull requests.
  3. Flip "Template repository"Settings → General → Template repository so your own "Use this template" button works.

Everything else (CI, Scorecard, CodeQL, Dependabot) works out of the box. Desired GitHub settings live in .github/desired-repo-settings.json.

What you get out of the box

  • Working vertical slice — one player, three pickups, walls, live HUD, save/load to localStorage. Proves the architecture end-to-end and is the pattern to mimic.
  • Architectural boundaries enforced by two independent toolseslint-plugin-boundaries in the editor/PR, dependency-cruiser as belt-and-braces in CI. Try importing phaser from src/domain/** and watch both reject it.
  • Seven code generators (bun run new:module|scene|feature|port|content|adr) so AI agents scaffold boilerplate instead of re-deriving it.
  • Spec-driven feature workflow via GitHub Spec Kit (/speckit:specify → :clarify → :plan → :tasks → :analyze → :implement) with a project constitution pointing at the architectural rules.
  • Canonical AI-facing docs (AGENTS.md, docs/ai/*) so every fresh session starts with the same context.
  • CI that enforces it allbun run check, Playwright smoke, CodeQL, Semgrep, OSV + bun audit, Gitleaks, OpenSSF Scorecard, plus a grep-based invariants job.
  • Release & dep automation — release-please for semantic versioning from conventional commits; Dependabot for grouped weekly updates.

Start here

If you are... Read next
A programmer who never shipped a game docs/learn/
A human starting a game (tsforge or GitHub template) BUILD_THE_GAME.md
An AI agent in a fresh session AGENTS.md + docs/ai/catalog.md
Just evaluating the architecture docs/ai/architecture.md
Looking for the rules docs/ai/contribution-contract.md + .specify/memory/constitution.md

Quickstart

bun install
bun run dev            # http://localhost:5173

Arrow keys or WASD to move. Walk onto a yellow circle to score. Press S to save, R to reset.

bun run check is the merge bar (typecheck, lint, format, knip, dep-cruise, tests). bun run validate is that plus the Playwright smoke.

Using tsforge

tsforge is the BoringStack TypeScript build harness.

New game — same wizard as BoringStack:

tsforge scaffold --archetype phaser --dest ./my-game
# or, in a tsforge session: /scaffold → Phaser → folder name
cd my-game
tsforge   # first prompt plans the game (scene / feature / content slices)

No Docker, no .env. The clone keeps this template's WASD demo; new work extends it. The gate is bun run check. Requires a tsforge build that includes the Phaser adapter (tsforge main; the next npm release after 0.51.1).

Existing clone — point tsforge at this tree. The phaser rule pack auto-applies from the phaser dependency (scene shutdown, no factories in update, branded keys). This repo's eslint.config.js covers a syntactic subset of that pack so bun run check stays honest without depending on a published tsforge.

Do not add .tsforge/scaffold-manifest.json here. That file is how tsforge configures the fullstack BoringStack template. tsforge writes .tsforge/scaffold.json (a receipt) after a Phaser scaffold; that is expected.

Architecture in 30 seconds

                 +--------+
                 |  app   |   composition root
                 +--------+
                     |
      +-----------+--+--+-----------+
      |           |     |           |
  +--------+  +--------+  +---------+
  | domain |  |content |  | shared  |   pure + data + common types
  +--------+  +--------+  +---------+
                     |
                 +--------+
                 |runtime |   Phaser, browser APIs
                 +--------+
Layer Responsibility
domain Pure state + behaviors. No engine. No wall-clock. No storage.
features Orchestrate domain + ports. Emit events. Never import Phaser.
runtime Phaser scenes, entities, input, audio, adapters for shared ports.
content Zod-validated definitions, levels, balance.
shared Leaf utilities — types, event bus, test fakes.
app Composition root. Wires ports, content, and the web entrypoint.

Full story: docs/ai/architecture.md.

Stack

Phaser 4 · TypeScript 6 (strict + verbatimModuleSyntax + noUncheckedIndexedAccess) · Vite 8 · Vitest 4 · ESLint 10 (flat) · dependency-cruiser · Playwright · Zod · husky + lint-staged · knip · Bun 1.3.14 · Node 24.

Scripts

Script What it does
bun run dev Start Vite dev server
bun run build Typecheck, then production build
bun run test Vitest unit + integration
bun run test:smoke Playwright smoke against a built bundle
bun run check The gate: typecheck + lint + format + knip + dep-cruise + test
bun run validate check plus Playwright smoke
bun run check:arch Just architectural checks (lint boundaries + dep-cruiser)
bun run catalog Regenerate docs/ai/catalog.md from src/

Generators

Script Generates
bun run new:module <Name> Domain module under src/domain/<name>/
bun run new:scene <Name> Phaser scene
bun run new:feature <Name> Feature orchestrator + test
bun run new:port <Name> Port interface stub + matching fake
bun run new:content <Name> Zod schema + sample JSON + validated loader
bun run new:adr "<Title>" Numbered ADR in docs/adr/

Slash commands (Claude Code)

Project commands Spec Kit commands (/speckit:*)
/check /speckit:specify
/new-module /speckit:clarify
/new-feature /speckit:plan
/new-scene /speckit:tasks
/review-slice /speckit:analyze
/verify-boundaries /speckit:implement
/speckit:checklist
/speckit:constitution

CI & automation

Every push/PR runs:

  • cibun run check (typecheck, lint, format, knip, catalog, dep-cruise, tests) plus Playwright smoke
  • codeql — static analysis with security-and-quality queries
  • security-deps — osv-scanner on bun.lock + bun audit --audit-level=high
  • security-sast — Semgrep (OWASP top ten + JS/TS)
  • security-secrets — Gitleaks (pinned binary, SHA256-verified)
  • arch-invariants — grep-based banned-pattern guard (phaser/Math.random/Date.now/localStorage in src/domain)

On main, OpenSSF Scorecard publishes SARIF weekly. release-please opens/updates a release PR from conventional commits. Dependabot opens grouped weekly PRs for bun and GitHub Actions.

License

MIT — see LICENSE.