code-quality-cocos
Code Quality — Cocos Creator / TypeScript
Section titled “Code Quality — Cocos Creator / TypeScript”Binding rule. Extends code-conventions-cocos.md (which governs naming and style); this file
governs structure and pattern choice. Auto-loaded, so it binds every session — an inline Edit,
a cocos-developer spawn, and a modularize refactor pass are all equally bound.
SSOT: architecture doctrine — SOLID, module boundaries, mandatory class roles, anti-patterns —
lives in the project’s docs/system-design.md (§ “Code Structure Rules (Mandatory)”, from
docs/system-design-template.md). This rule does not restate it; a second copy would drift.
Read the design doc for what good looks like; read this rule for when you are obliged to act;
load t1k-cocos-base-architecture-patterns for the reasoning and the audit.
Any time you write, refactor, or review Cocos TypeScript:
docs/system-design.mdgoverns. Its Code Structure Rules are binding, not reference material. If the project has no design doc, or it no longer matches the code, that is a blocking finding — author or correct it before planning structural work (Phase 0 in the patterns skill). You cannot grade architecture without a stated target.- The pattern triggers below are mandatory. A change that introduces a listed violation is incomplete, not merely imperfect.
- Annotation moves with the code (below).
Mandatory pattern triggers
Section titled “Mandatory pattern triggers”The design doc’s anti-patterns table says don’t do X. This says when you must introduce Y — the gap the template leaves.
| If you see | You must apply | Why |
|---|---|---|
instantiate() / new Node() in a loop, or per-spawn during gameplay | Object pooling (ObjectPoolManager) | GC spikes mid-gameplay; the #1 playable framedrop cause |
2+ boolean flags encoding “what is happening now” (_isDead, _isPaused) | FSM (StateManager) | Boolean-combination states drift into unreachable/contradictory combos |
| A module reaching into another module directly | SignalBus (named-method subscribe) | Already banned by the design doc’s module-boundary rule; it is also what blocks a later package swap |
| A class with 3+ unrelated change reasons | Component split (SRP) | Blocks reuse and makes every later change a merge conflict. Line count is a symptom — run the change-reason test, not a wc -l check |
| Global mutable state reached from 3+ call sites | Service singleton (private static _instance) | Ad-hoc globals have no init order and no teardown |
Pattern APIs are taught by their own skills (t1k-cocos-playable-object-pool,
-fsm, -signalbus). This rule decides when they are required; those skills decide how.
Enabling extraction — quality work that unblocks reuse
Section titled “Enabling extraction — quality work that unblocks reuse”When a subsystem cannot be swapped for a published @playablelabs/* package because it is fused
into a larger class, the SRP split that exposes that seam is required refactor work, not
optional cleanup. Reuse and architecture are not independent: the split is what makes the swap
possible. Record it as an enabling extraction so the reuse scan re-runs against the new seam.
Annotation moves with the code
Section titled “Annotation moves with the code”Any symbol you add or whose signature you change carries its TSDoc /** */ in the same change.
Never leave annotation as a follow-up pass — docs that lag the code are worse than absent docs,
because they read as authoritative.
- Write annotation inline as you edit, or run
node scripts/docs-ts.cjs annotate <src> <overrides.json>fromt1k-cocos-base-script-graph. - The
annotatescript rewrites source in place — clean git tree or--dry-runfirst. - Coverage may be audited read-only at any time, without triggering a refactor and without writing
anything:
docs-ts.cjs audit <src> [--by module|file] [--json <out>] [--min-coverage N].
Applying this during a refactor
Section titled “Applying this during a refactor”t1k-cocos-playable-modularize-refactor runs Phase 0 (design doc author-or-audit) first, then
executes this rule as Tier 2.5 of its ordered plan — after easy reuse swaps, before package
migration — with a second reuse pass (Tier 2.75) over the seams the extractions expose. The
architecture audit runs early as a plan input; the apply runs in tier order behind the family’s
normal gate.
Anti-patterns
Section titled “Anti-patterns”- Restating the design doc’s architecture rules in a skill, plan, or agent brief. One copy, in
docs/system-design.md. - Planning a refactor against a design doc known to be stale. Correct it first.
- In Phase 0 on a legacy project, documenting the aspiration instead of what the code does today.
- Treating the trigger table as a code-review suggestion — it is a completion gate.
- Refactoring code that a reuse swap is about to delete. Check the reuse scan first.
- Deferring annotation to “a docs pass later.” There is no later.
- Manufacturing interfaces to tick LSP/ISP boxes on code with one implementation.
Related
Section titled “Related”docs/system-design.md(per project) — SSOT for architecture doctrine. Blank:docs/system-design-template.md. Filled reference:docs/system-design-example.md.code-conventions-cocos.md— naming and style sibling: that one is what it’s called, this one is how it’s shaped.t1k-cocos-base-architecture-patterns— pattern triggers, enabling extraction, the audit. Read-only.t1k-cocos-base-system-design— ownsdocs/system-design.mdas an artifact: template, module-table contract, and the generate/verify/migrate scripts.t1k-cocos-playable-modularize-refactor— where this rule executes at project scale.- Core
code-conventions.md§ “Modular Boundaries — Seam Where It Earns Its Keep” — the seam-worth test the enabling-extraction clause depends on.