Skip to content

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:

  1. docs/system-design.md governs. 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.
  2. The pattern triggers below are mandatory. A change that introduces a listed violation is incomplete, not merely imperfect.
  3. Annotation moves with the code (below).

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 seeYou must applyWhy
instantiate() / new Node() in a loop, or per-spawn during gameplayObject 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 directlySignalBus (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 reasonsComponent 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 sitesService 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.

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> from t1k-cocos-base-script-graph.
  • The annotate script rewrites source in place — clean git tree or --dry-run first.
  • 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].

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.

  • 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.
  • 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 — owns docs/system-design.md as 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.