`project.yaml` at the repo root is now the single source of truth for a project's configuration, replacing `production/stage.txt`, `production/review-mode.txt` and `.claude/docs/technical-preferences.md` (all three still read as a fallback; nothing is force-deleted). **`modes.rigor` — one question instead of six.** `minimal`, `standard` or `full` fronts six knobs: `modes.workflow`, `docs.density`, `qa.level`, `modes.story_granularity`, `modes.review_mode` and `team.size`. It defaults to `minimal`, which is a change from 1.0's behaviour: the heavier tier was measured costing several times more to reach working code without producing a better result, and returning nothing when a fresh developer inherited the project. Pin `modes.rigor: standard` to keep 1.0's process level. Also in this release: - `/settings` to view or change any setting, and `project.local.yaml` for per-developer preferences that should not be committed. - `system_overrides` to hold one system to a higher standard than the rest of the project, and `testing.strict` to set per test type whether missing evidence blocks a story or warns. - A story that changes anything the player sees is not closed until the game has been launched, observed, and a screenshot retained in `production/qa/evidence/`. A parse check is not a run. This holds at every rigor level, including `minimal`, where automated tests are waived but the look is not. - The code root is engine-specific and enforced as such: Godot `src/`, Unity `Assets/`, Unreal `Source/<Module>/`. Two of the three will not build a project laid out any other way. - Migration tooling for existing projects: `.claude/scripts/migrate-v1-config.sh` converts a 1.0 layout, non-destructively by default, with a report to review before `--finalize` deletes anything. - Ask-before-write holds regardless of personal automation settings. Upgrading from 1.0 or earlier: see UPGRADING.md. Full list of changes: CHANGELOG.md. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016xvzG3i7pWQg4LjyDwWMXd
5.7 KiB
Coding Standards
- All game code must include doc comments on public APIs
- Architecture decisions are recorded as ADRs in
docs/architecture/. How many is set bymodes.workflow— all ADRs atfull, critical ADRs only atstandard, and none required atminimal, where the decision log anddesign/game-brief.mdcarry the rationale instead. See.claude/docs/workflow-modes.md. - Gameplay values must be data-driven (external config), never hardcoded
- All public methods must be unit-testable (dependency injection over singletons)
- Commits must reference the relevant design document or task ID
- Commit messages: Use Conventional Commits format —
feat:,fix:,chore:,docs:,test:,refactor:. Reference the story or task ID in the body (e.g.,Story: EPIC-001-S02). - Verification-driven development: Write tests first when adding gameplay systems. For UI changes, verify with screenshots. Compare expected output to actual output before marking work complete. Every implementation should have a way to prove it works.
- A parse check is not a run. Every story that changes something
player-observable is launched and observed before it closes, and the
observation is a retained screenshot in
production/qa/evidence/. Procedure per engine:.claude/docs/run-and-observe.md. Not waived atqa.level: minimal— tests are, the look is not.
Design Document Standards
- All design docs use Markdown
- Each mechanic has a dedicated document in
design/gdd/ - How many of the 8 sections are required depends on
modes.workflow— all 8 atfull, 5 (+ Formulas when the system defines numeric rules — rates, curves, thresholds, costs; the system'sCategoryis a hint, not the test) atstandard, and no GDD at all atminimal, wheredesign/game-brief.mdis the design record. See.claude/docs/workflow-modes.md. The 8 sections:- Overview -- one-paragraph summary
- Player Fantasy -- intended feeling and experience
- Detailed Rules -- unambiguous mechanics
- Formulas -- all math defined with variables
- Edge Cases -- unusual situations handled
- Dependencies -- other systems listed
- Tuning Knobs -- configurable values identified
- Acceptance Criteria -- testable success conditions
- Balance values must link to their source formula or rationale
Testing Standards
Test Evidence by Story Type
All stories must have appropriate test evidence before they can be marked Done:
| Story Type | Required Evidence | Location | Default Gate Level |
|---|---|---|---|
| Logic (formulas, AI, state machines) | Automated unit test — must pass | tests/unit/[system]/ |
BLOCKING |
| Integration (multi-system) | Integration test OR documented playtest | tests/integration/[system]/ |
BLOCKING |
| Visual/Feel (animation, VFX, feel) | Retained screenshot + lead sign-off | production/qa/evidence/ |
BLOCKING |
| UI (menus, HUD, screens) | Retained screenshot of each screen touched | production/qa/evidence/ |
BLOCKING |
| Config/Data (balance tuning) | Smoke check pass | production/qa/smoke-[date].md |
ADVISORY |
The Default Gate Level applies when testing.strict is not set in
project.yaml. A project may override it per test type: testing.strict.logic,
.integration, .visual, .ui, and .config each take true (BLOCKING) or
false (ADVISORY). /story-done, /story-readiness, /dev-story,
/gate-check, and /smoke-check resolve the effective level from that setting,
falling back to the defaults above when it is absent.
Why Visual and UI block. "Retained" is load-bearing — the screenshot must still be on disk in
production/qa/evidence/when the story is closed. One that was captured and discarded is an assertion, not evidence. These two rows block because for a game the way it looks is the product: an advisory visual gate gets deferred in favour of whatever does block, and the result is a well-tested game that looks wrong.
Exception —
/smoke-check. The ADVISORY default for Config/Data above applies to per-story evidence gates./smoke-checkis a build-health gate, not a per-story evidence gate, so its own unset default fortesting.strict.configis BLOCKING. This divergence is intentional and is documented at both sites; do not reconcile one to the other.
Automated Test Rules
- Naming:
[system]_[feature]_test.[ext]for files;test_[scenario]_[expected]for functions - Determinism: Tests must produce the same result every run — no random seeds, no time-dependent assertions
- Isolation: Each test sets up and tears down its own state; tests must not depend on execution order
- No hardcoded data: Test fixtures use constant files or factory functions, not inline magic numbers (exception: boundary value tests where the exact number IS the point)
- Independence: Unit tests do not call external APIs, databases, or file I/O — use dependency injection
What NOT to Automate
- Visual fidelity (shader output, VFX appearance, animation curves)
- "Feel" qualities (input responsiveness, perceived weight, timing)
- Platform-specific rendering (test on target hardware, not headlessly)
- Full gameplay sessions (covered by playtesting, not automation)
CI/CD Rules
- Automated test suite runs on every push to main and every PR
- No merge if tests fail — tests are a blocking gate in CI
- Never disable or skip failing tests to make CI pass — fix the underlying issue
- Engine-specific CI commands:
- Godot:
godot --headless --script tests/gdunit4_runner.gd - Unity:
game-ci/unity-test-runner@v4(GitHub Actions) - Unreal: headless runner with
-nullrhiflag
- Godot: