theone-cocos-standards

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

TheOne Studio Cocos Creator Development Standards

TheOne Studio Cocos Creator 开发标准

⚠️ Cocos Creator 3.x (TypeScript 4.1+): All patterns and examples are compatible with Cocos Creator 3.x playable ads development.
⚠️ Cocos Creator 3.x(TypeScript 4.1+): 所有模式和示例均兼容Cocos Creator 3.x可玩广告开发。

Skill Purpose

技能目标

This skill enforces TheOne Studio's comprehensive Cocos Creator development standards with CODE QUALITY FIRST:
Priority 1: Code Quality & Hygiene (MOST IMPORTANT)
  • TypeScript strict mode, ESLint configuration, access modifiers (public/private/protected)
  • Throw exceptions (never silent errors)
  • console.log for development, remove in production builds
  • readonly for immutable fields, const for constants
  • No inline comments (use descriptive names)
  • Proper error handling and type safety
Priority 2: Modern TypeScript Patterns
  • Array methods (map/filter/reduce) over loops
  • Arrow functions, destructuring, spread operators
  • Optional chaining, nullish coalescing
  • Type guards, utility types (Partial, Required, Readonly)
  • Modern TypeScript features
Priority 3: Cocos Creator Architecture
  • Component-based Entity-Component (EC) system
  • Lifecycle methods: onLoad→start→onEnable→update→onDisable→onDestroy
  • EventDispatcher pattern for custom events
  • Node event system (EventTouch, keyboard events)
  • Resource management and pooling for playables
Priority 4: Playable Ads Performance
  • DrawCall batching (<10 DrawCalls target)
  • Sprite atlas configuration (auto-atlas enabled)
  • GPU skinning for skeletal animations
  • Zero allocations in update() loop
  • Bundle size <5MB (texture compression, code minification)
本技能以代码质量优先为原则,强制执行TheOne Studio的Cocos Creator全面开发标准:
优先级1:代码质量与规范(最重要)
  • TypeScript严格模式、ESLint配置、访问修饰符(public/private/protected)
  • 抛出异常(绝不允许静默错误)
  • console.log仅用于开发环境,生产构建中需移除
  • 只读字段使用readonly,常量使用const
  • 禁止行内注释(使用具名化的命名)
  • 完善的错误处理与类型安全
优先级2:现代TypeScript模式
  • 优先使用数组方法(map/filter/reduce)而非循环
  • 箭头函数、解构赋值、扩展运算符
  • 可选链操作符、空值合并运算符
  • 类型守卫、工具类型(Partial、Required、Readonly)
  • 现代TypeScript特性
优先级3:Cocos Creator架构
  • 基于组件的实体-组件(EC)系统
  • 生命周期方法:onLoad→start→onEnable→update→onDisable→onDestroy
  • 自定义事件的EventDispatcher模式
  • 节点事件系统(EventTouch、键盘事件)
  • 可玩广告的资源管理与对象池
优先级4:可玩广告性能优化
  • DrawCall批处理(目标<10次DrawCall)
  • 精灵图集配置(启用自动图集)
  • 骨骼动画的GPU蒙皮
  • update()循环中零内存分配
  • 包体大小<5MB(纹理压缩、代码压缩)

When This Skill Triggers

本技能的触发场景

  • Writing or refactoring Cocos Creator TypeScript code
  • Implementing playable ads features
  • Working with component lifecycle and events
  • Optimizing performance for playable ads
  • Reviewing code changes or pull requests
  • Setting up playable project architecture
  • Reducing bundle size or DrawCall counts
  • 编写或重构Cocos Creator TypeScript代码
  • 实现可玩广告功能
  • 处理组件生命周期与事件
  • 优化可玩广告的性能
  • 审查代码变更或合并请求
  • 搭建可玩广告项目架构
  • 减小包体大小或DrawCall数量

Quick Reference Guide

快速参考指南

What Do You Need Help With?

你需要哪方面的帮助?

PriorityTaskReference
🔴 PRIORITY 1: Code Quality (Check FIRST)
1TypeScript strict mode, ESLint, access modifiersQuality & Hygiene
1Throw exceptions, proper error handlingQuality & Hygiene
1console.log (development only), remove in productionQuality & Hygiene
1readonly/const, no inline comments, descriptive namesQuality & Hygiene
🟡 PRIORITY 2: Modern TypeScript Patterns
2Array methods, arrow functions, destructuringModern TypeScript
2Optional chaining, nullish coalescingModern TypeScript
2Type guards, utility typesModern TypeScript
🟢 PRIORITY 3: Cocos Architecture
3Component system, @property decoratorComponent System
3Lifecycle methods (onLoad→start→update→onDestroy)Component System
3EventDispatcher, Node events, cleanupEvent Patterns
3Resource loading, pooling, memory managementPlayable Optimization
🔵 PRIORITY 4: Performance & Review
4DrawCall batching, sprite atlas, GPU skinningPlayable Optimization
4Update loop optimization, zero allocationsPerformance
4Bundle size reduction (<5MB target)Size Optimization
4Architecture review (components, lifecycle, events)Architecture Review
4TypeScript quality reviewQuality Review
4Performance review (DrawCalls, allocations)Performance Review
优先级任务参考文档
🔴 优先级1:代码质量(首先检查)
1TypeScript严格模式、ESLint、访问修饰符质量与规范
1抛出异常、完善的错误处理质量与规范
1console.log(仅开发环境)、生产构建中移除质量与规范
1readonly/const、禁止行内注释、具名化命名质量与规范
🟡 优先级2:现代TypeScript模式
2数组方法、箭头函数、解构赋值现代TypeScript
2可选链操作符、空值合并运算符现代TypeScript
2类型守卫、工具类型现代TypeScript
🟢 优先级3:Cocos架构
3组件系统、@property装饰器组件系统
3生命周期方法(onLoad→start→update→onDestroy)组件系统
3EventDispatcher、节点事件、清理工作事件模式
3资源加载、对象池、内存管理可玩广告优化
🔵 优先级4:性能与审查
4DrawCall批处理、精灵图集、GPU蒙皮可玩广告优化
4Update循环优化、零内存分配性能优化
4包体大小缩减(目标<5MB)大小优化
4架构审查(组件、生命周期、事件)架构审查
4TypeScript质量审查质量审查
4性能审查(DrawCall、内存分配)性能审查

🔴 CRITICAL: Code Quality Rules (CHECK FIRST!)

🔴 关键:代码质量规则(首先检查!)

⚠️ MANDATORY QUALITY STANDARDS

⚠️ 强制质量标准

ALWAYS enforce these BEFORE writing any code:
  1. Enable TypeScript strict mode - "strict": true in tsconfig.json
  2. Use ESLint configuration - @typescript-eslint rules enabled
  3. Use access modifiers - public/private/protected on all members
  4. Throw exceptions for errors - NEVER silent failures or undefined returns
  5. console.log for development only - Remove all console statements in production builds
  6. Use readonly for immutable fields - Mark fields that aren't reassigned
  7. Use const for constants - Constants should be const, not let
  8. No inline comments - Use descriptive names; code should be self-explanatory
  9. Proper null/undefined handling - Use optional chaining and nullish coalescing
  10. Type safety - Avoid
    any
    type, use proper types and interfaces
Example: Enforce Quality First
typescript
// ✅ EXCELLENT: All quality rules enforced
import { _decorator, Component, Node, EventTouch } from 'cc';
const { ccclass, property } = _decorator;

@ccclass('PlayerController')
export class PlayerController extends Component {
    // 3. Access modifier, 6. readonly for immutable
    @property(Node)
    private readonly targetNode: Node | null = null;

    // 7. const for constants
    private static readonly MAX_HEALTH: number = 100;
    private currentHealth: number = 100;

    // Lifecycle: onLoad → start → onEnable
    protected onLoad(): void {
        // 4. Throw exception for errors
        if (!this.targetNode) {
            throw new Error('PlayerController: targetNode is not assigned');
        }

        // 9. Proper event listener setup
        this.node.on(Node.EventType.TOUCH_START, this.onTouchStart, this);
    }

    protected onDestroy(): void {
        // 9. Always cleanup event listeners
        this.node.off(Node.EventType.TOUCH_START, this.onTouchStart, this);
    }

    private onTouchStart(event: EventTouch): void {
        // 5. console.log only for development (remove in production)
        if (CC_DEBUG) {
            console.log('Touch detected');
        }

        this.takeDamage(10);
    }

    // 8. Descriptive method names (no inline comments needed)
    private takeDamage(amount: number): void {
        this.currentHealth -= amount;

        if (this.currentHealth <= 0) {
            this.handlePlayerDeath();
        }
    }

    private handlePlayerDeath(): void {
        // Death logic
    }
}
在编写任何代码前,必须强制执行以下规则:
  1. 启用TypeScript严格模式 - 在tsconfig.json中设置"strict": true
  2. 使用ESLint配置 - 启用@typescript-eslint规则
  3. 使用访问修饰符 - 所有成员均需添加public/private/protected
  4. 错误时抛出异常 - 绝不允许静默失败或返回undefined
  5. console.log仅用于开发环境 - 生产构建中移除所有console语句
  6. 只读字段使用readonly - 标记无需重新赋值的字段
  7. 常量使用const - 常量必须用const,而非let
  8. 禁止行内注释 - 使用具名化命名;代码应具有自解释性
  9. 完善的null/undefined处理 - 使用可选链操作符和空值合并运算符
  10. 类型安全 - 避免使用
    any
    类型,使用正确的类型和接口
示例:优先保证代码质量
typescript
// ✅ 优秀:遵循所有质量规则
import { _decorator, Component, Node, EventTouch } from 'cc';
const { ccclass, property } = _decorator;

@ccclass('PlayerController')
export class PlayerController extends Component {
    // 3. 访问修饰符,6. 只读字段
    @property(Node)
    private readonly targetNode: Node | null = null;

    // 7. 常量使用const
    private static readonly MAX_HEALTH: number = 100;
    private currentHealth: number = 100;

    // 生命周期:onLoad → start → onEnable
    protected onLoad(): void {
        // 4. 错误时抛出异常
        if (!this.targetNode) {
            throw new Error('PlayerController: targetNode未赋值');
        }

        // 9. 正确设置事件监听器
        this.node.on(Node.EventType.TOUCH_START, this.onTouchStart, this);
    }

    protected onDestroy(): void {
        // 9. 始终清理事件监听器
        this.node.off(Node.EventType.TOUCH_START, this.onTouchStart, this);
    }

    private onTouchStart(event: EventTouch): void {
        // 5. console.log仅用于开发环境(生产构建中移除)
        if (CC_DEBUG) {
            console.log('检测到触摸');
        }

        this.takeDamage(10);
    }

    // 8. 具名化方法名(无需行内注释)
    private takeDamage(amount: number): void {
        this.currentHealth -= amount;

        if (this.currentHealth <= 0) {
            this.handlePlayerDeath();
        }
    }

    private handlePlayerDeath(): void {
        // 死亡逻辑
    }
}

⚠️ Cocos Creator Architecture Rules (AFTER Quality)

⚠️ Cocos Creator架构规则(在保证质量之后)

Component System Fundamentals

组件系统基础

Entity-Component (EC) System:
  • Components extend
    Component
    class
  • Use
    @ccclass
    and
    @property
    decorators
  • Lifecycle: onLoad → start → onEnable → update → lateUpdate → onDisable → onDestroy
Execution Order:
  1. onLoad() - Component initialization, one-time setup
  2. start() - After all components loaded, can reference other components
  3. onEnable() - When component/node enabled (can be called multiple times)
  4. update(dt) - Every frame (use sparingly for playables)
  5. lateUpdate(dt) - After all update() calls
  6. onDisable() - When component/node disabled
  7. onDestroy() - Cleanup, remove listeners, release resources
Universal Rules:
  • ✅ Initialize in onLoad(), reference other components in start()
  • ✅ Register events in onEnable(), unregister in onDisable()
  • ✅ Always cleanup listeners in onDestroy()
  • ✅ Avoid heavy logic in update() (performance critical for playables)
  • ✅ Use readonly for @property fields that shouldn't be reassigned
  • ✅ Throw exceptions for missing required references
实体-组件(EC)系统:
  • 组件继承
    Component
  • 使用
    @ccclass
    @property
    装饰器
  • 生命周期:onLoad → start → onEnable → update → lateUpdate → onDisable → onDestroy
执行顺序:
  1. onLoad() - 组件初始化,一次性设置
  2. start() - 所有组件加载完成后执行,可引用其他组件
  3. onEnable() - 组件/节点启用时执行(可多次调用)
  4. update(dt) - 每帧执行(可玩广告中需谨慎使用)
  5. lateUpdate(dt) - 所有update()调用完成后执行
  6. onDisable() - 组件/节点禁用时执行
  7. onDestroy() - 清理工作,移除监听器,释放资源
通用规则:
  • ✅ 在onLoad()中初始化,在start()中引用其他组件
  • ✅ 在onEnable()中注册事件,在onDisable()中注销事件
  • ✅ 始终在onDestroy()中清理监听器
  • ✅ 避免在update()中执行重逻辑(可玩广告的性能关键)
  • ✅ 对于不应重新赋值的@property字段,使用readonly
  • ✅ 对于缺失的必要引用,抛出异常

Brief Examples

简短示例

🔴 Code Quality First

🔴 优先保证代码质量

typescript
// ✅ EXCELLENT: Quality rules enforced
import { _decorator, Component, Node } from 'cc';
const { ccclass, property } = _decorator;

@ccclass('GameManager')
export class GameManager extends Component {
    @property(Node)
    private readonly playerNode: Node | null = null;

    private static readonly MAX_SCORE: number = 1000;
    private currentScore: number = 0;

    protected onLoad(): void {
        // Throw exception for missing required references
        if (!this.playerNode) {
            throw new Error('GameManager: playerNode is required');
        }

        if (CC_DEBUG) {
            console.log('GameManager initialized'); // Development only
        }
    }

    public addScore(points: number): void {
        if (points <= 0) {
            throw new Error('GameManager.addScore: points must be positive');
        }

        this.currentScore = Math.min(
            this.currentScore + points,
            GameManager.MAX_SCORE
        );
    }
}
typescript
// ✅ 优秀:遵循质量规则
import { _decorator, Component, Node } from 'cc';
const { ccclass, property } = _decorator;

@ccclass('GameManager')
export class GameManager extends Component {
    @property(Node)
    private readonly playerNode: Node | null = null;

    private static readonly MAX_SCORE: number = 1000;
    private currentScore: number = 0;

    protected onLoad(): void {
        // 缺失必要引用时抛出异常
        if (!this.playerNode) {
            throw new Error('GameManager: playerNode为必填项');
        }

        if (CC_DEBUG) {
            console.log('GameManager已初始化'); // 仅开发环境
        }
    }

    public addScore(points: number): void {
        if (points <= 0) {
            throw new Error('GameManager.addScore: 分数必须为正数');
        }

        this.currentScore = Math.min(
            this.currentScore + points,
            GameManager.MAX_SCORE
        );
    }
}

🟡 Modern TypeScript Patterns

🟡 现代TypeScript模式

typescript
// ✅ GOOD: Array methods instead of loops
const activeEnemies = allEnemies.filter(e => e.isActive);
const enemyPositions = activeEnemies.map(e => e.node.position);

// ✅ GOOD: Optional chaining and nullish coalescing
const playerName = player?.name ?? 'Unknown';

// ✅ GOOD: Destructuring
const { x, y } = this.node.position;

// ✅ GOOD: Arrow functions
this.enemies.forEach(enemy => enemy.takeDamage(10));

// ✅ GOOD: Type guards
function isPlayer(node: Node): node is PlayerNode {
    return node.getComponent(PlayerController) !== null;
}
typescript
// ✅ 良好:使用数组方法而非循环
const activeEnemies = allEnemies.filter(e => e.isActive);
const enemyPositions = activeEnemies.map(e => e.node.position);

// ✅ 良好:可选链操作符和空值合并运算符
const playerName = player?.name ?? 'Unknown';

// ✅ 良好:解构赋值
const { x, y } = this.node.position;

// ✅ 良好:箭头函数
this.enemies.forEach(enemy => enemy.takeDamage(10));

// ✅ 良好:类型守卫
function isPlayer(node: Node): node is PlayerNode {
    return node.getComponent(PlayerController) !== null;
}

🟢 Cocos Creator Component Pattern

🟢 Cocos Creator组件模式

typescript
import { _decorator, Component, Node, EventTouch, Vec3 } from 'cc';
const { ccclass, property } = _decorator;

@ccclass('TouchHandler')
export class TouchHandler extends Component {
    @property(Node)
    private readonly targetNode: Node | null = null;

    private readonly tempVec3: Vec3 = new Vec3(); // Reusable vector

    // 1. onLoad: Initialize component
    protected onLoad(): void {
        if (!this.targetNode) {
            throw new Error('TouchHandler: targetNode is required');
        }
    }

    // 2. start: Reference other components (if needed)
    protected start(): void {
        // Can safely access other components here
    }

    // 3. onEnable: Register event listeners
    protected onEnable(): void {
        this.node.on(Node.EventType.TOUCH_START, this.onTouchStart, this);
        this.node.on(Node.EventType.TOUCH_MOVE, this.onTouchMove, this);
    }

    // 4. onDisable: Unregister event listeners
    protected onDisable(): void {
        this.node.off(Node.EventType.TOUCH_START, this.onTouchStart, this);
        this.node.off(Node.EventType.TOUCH_MOVE, this.onTouchMove, this);
    }

    // 5. onDestroy: Final cleanup
    protected onDestroy(): void {
        // Release any additional resources
    }

    private onTouchStart(event: EventTouch): void {
        // Handle touch
    }

    private onTouchMove(event: EventTouch): void {
        // Reuse vector to avoid allocations
        this.targetNode!.getPosition(this.tempVec3);
        this.tempVec3.y += 10;
        this.targetNode!.setPosition(this.tempVec3);
    }
}
typescript
import { _decorator, Component, Node, EventTouch, Vec3 } from 'cc';
const { ccclass, property } = _decorator;

@ccclass('TouchHandler')
export class TouchHandler extends Component {
    @property(Node)
    private readonly targetNode: Node | null = null;

    private readonly tempVec3: Vec3 = new Vec3(); // 可复用向量

    // 1. onLoad: 初始化组件
    protected onLoad(): void {
        if (!this.targetNode) {
            throw new Error('TouchHandler: targetNode为必填项');
        }
    }

    // 2. start: 引用其他组件(如有需要)
    protected start(): void {
        // 此处可安全访问其他组件
    }

    // 3. onEnable: 注册事件监听器
    protected onEnable(): void {
        this.node.on(Node.EventType.TOUCH_START, this.onTouchStart, this);
        this.node.on(Node.EventType.TOUCH_MOVE, this.onTouchMove, this);
    }

    // 4. onDisable: 注销事件监听器
    protected onDisable(): void {
        this.node.off(Node.EventType.TOUCH_START, this.onTouchStart, this);
        this.node.off(Node.EventType.TOUCH_MOVE, this.onTouchMove, this);
    }

    // 5. onDestroy: 最终清理
    protected onDestroy(): void {
        // 释放其他资源
    }

    private onTouchStart(event: EventTouch): void {
        // 处理触摸事件
    }

    private onTouchMove(event: EventTouch): void {
        // 复用向量以避免内存分配
        this.targetNode!.getPosition(this.tempVec3);
        this.tempVec3.y += 10;
        this.targetNode!.setPosition(this.tempVec3);
    }
}

🟢 Event Dispatcher Pattern

🟢 EventDispatcher模式

typescript
import { _decorator, Component, EventTarget } from 'cc';
const { ccclass } = _decorator;

// Custom event types
export enum GameEvent {
    SCORE_CHANGED = 'score_changed',
    LEVEL_COMPLETE = 'level_complete',
    PLAYER_DIED = 'player_died',
}

export interface ScoreChangedEvent {
    oldScore: number;
    newScore: number;
}

@ccclass('EventManager')
export class EventManager extends Component {
    private static instance: EventManager | null = null;
    private readonly eventTarget: EventTarget = new EventTarget();

    protected onLoad(): void {
        if (EventManager.instance) {
            throw new Error('EventManager: instance already exists');
        }
        EventManager.instance = this;
    }

    public static emit(event: GameEvent, data?: any): void {
        if (!EventManager.instance) {
            throw new Error('EventManager: instance not initialized');
        }
        EventManager.instance.eventTarget.emit(event, data);
    }

    public static on(event: GameEvent, callback: Function, target?: any): void {
        if (!EventManager.instance) {
            throw new Error('EventManager: instance not initialized');
        }
        EventManager.instance.eventTarget.on(event, callback, target);
    }

    public static off(event: GameEvent, callback: Function, target?: any): void {
        if (!EventManager.instance) {
            throw new Error('EventManager: instance not initialized');
        }
        EventManager.instance.eventTarget.off(event, callback, target);
    }
}

// Usage in component
@ccclass('ScoreDisplay')
export class ScoreDisplay extends Component {
    protected onEnable(): void {
        EventManager.on(GameEvent.SCORE_CHANGED, this.onScoreChanged, this);
    }

    protected onDisable(): void {
        EventManager.off(GameEvent.SCORE_CHANGED, this.onScoreChanged, this);
    }

    private onScoreChanged(data: ScoreChangedEvent): void {
        console.log(`Score: ${data.oldScore}${data.newScore}`);
    }
}
typescript
import { _decorator, Component, EventTarget } from 'cc';
const { ccclass } = _decorator;

// 自定义事件类型
export enum GameEvent {
    SCORE_CHANGED = 'score_changed',
    LEVEL_COMPLETE = 'level_complete',
    PLAYER_DIED = 'player_died',
}

export interface ScoreChangedEvent {
    oldScore: number;
    newScore: number;
}

@ccclass('EventManager')
export class EventManager extends Component {
    private static instance: EventManager | null = null;
    private readonly eventTarget: EventTarget = new EventTarget();

    protected onLoad(): void {
        if (EventManager.instance) {
            throw new Error('EventManager: 实例已存在');
        }
        EventManager.instance = this;
    }

    public static emit(event: GameEvent, data?: any): void {
        if (!EventManager.instance) {
            throw new Error('EventManager: 实例未初始化');
        }
        EventManager.instance.eventTarget.emit(event, data);
    }

    public static on(event: GameEvent, callback: Function, target?: any): void {
        if (!EventManager.instance) {
            throw new Error('EventManager: 实例未初始化');
        }
        EventManager.instance.eventTarget.on(event, callback, target);
    }

    public static off(event: GameEvent, callback: Function, target?: any): void {
        if (!EventManager.instance) {
            throw new Error('EventManager: 实例未初始化');
        }
        EventManager.instance.eventTarget.off(event, callback, target);
    }
}

// 在组件中使用
@ccclass('ScoreDisplay')
export class ScoreDisplay extends Component {
    protected onEnable(): void {
        EventManager.on(GameEvent.SCORE_CHANGED, this.onScoreChanged, this);
    }

    protected onDisable(): void {
        EventManager.off(GameEvent.SCORE_CHANGED, this.onScoreChanged, this);
    }

    private onScoreChanged(data: ScoreChangedEvent): void {
        console.log(`分数: ${data.oldScore}${data.newScore}`);
    }
}

🔵 Playable Performance Optimization

🔵 可玩广告性能优化

typescript
import { _decorator, Component, Node, Sprite, SpriteAtlas } from 'cc';
const { ccclass, property } = _decorator;

@ccclass('OptimizedSpriteManager')
export class OptimizedSpriteManager extends Component {
    // Use sprite atlas for DrawCall batching
    @property(SpriteAtlas)
    private readonly characterAtlas: SpriteAtlas | null = null;

    // Preallocate arrays to avoid allocations in update()
    private readonly tempNodes: Node[] = [];
    private frameCount: number = 0;

    protected onLoad(): void {
        if (!this.characterAtlas) {
            throw new Error('OptimizedSpriteManager: characterAtlas is required');
        }

        // Prewarm sprite frames from atlas
        this.prewarmSpriteFrames();
    }

    private prewarmSpriteFrames(): void {
        // Load all sprites from atlas (batched in single DrawCall)
        const spriteFrame = this.characterAtlas!.getSpriteFrame('character_idle');
        if (!spriteFrame) {
            throw new Error('Sprite frame not found in atlas');
        }
    }

    // Optimize update: avoid allocations, use object pooling
    protected update(dt: number): void {
        // Run expensive operations every N frames instead of every frame
        this.frameCount++;
        if (this.frameCount % 10 === 0) {
            this.updateExpensiveOperation();
        }
    }

    private updateExpensiveOperation(): void {
        // Reuse array instead of creating new one
        this.tempNodes.length = 0;

        // Batch operations to reduce DrawCalls
    }
}
typescript
import { _decorator, Component, Node, Sprite, SpriteAtlas } from 'cc';
const { ccclass, property } = _decorator;

@ccclass('OptimizedSpriteManager')
export class OptimizedSpriteManager extends Component {
    // 使用精灵图集进行DrawCall批处理
    @property(SpriteAtlas)
    private readonly characterAtlas: SpriteAtlas | null = null;

    // 预分配数组以避免在update()中分配内存
    private readonly tempNodes: Node[] = [];
    private frameCount: number = 0;

    protected onLoad(): void {
        if (!this.characterAtlas) {
            throw new Error('OptimizedSpriteManager: characterAtlas为必填项');
        }

        // 预加载图集精灵帧
        this.prewarmSpriteFrames();
    }

    private prewarmSpriteFrames(): void {
        // 从图集加载所有精灵(批处理为单次DrawCall)
        const spriteFrame = this.characterAtlas!.getSpriteFrame('character_idle');
        if (!spriteFrame) {
            throw new Error('图集中未找到精灵帧');
        }
    }

    // 优化update:避免内存分配,使用对象池
    protected update(dt: number): void {
        // 每N帧执行一次耗时操作,而非每帧执行
        this.frameCount++;
        if (this.frameCount % 10 === 0) {
            this.updateExpensiveOperation();
        }
    }

    private updateExpensiveOperation(): void {
        // 复用数组而非创建新数组
        this.tempNodes.length = 0;

        // 批处理操作以减少DrawCall
    }
}

Code Review Checklist

代码审查清单

Quick Validation (before committing)

快速验证(提交前)

🔴 Code Quality (CHECK FIRST):
  • TypeScript strict mode enabled in tsconfig.json
  • ESLint rules passing (no errors)
  • All access modifiers correct (public/private/protected)
  • Exceptions thrown for errors (no silent failures)
  • console.log removed or wrapped in CC_DEBUG
  • readonly used for non-reassigned fields
  • const used for constants
  • No inline comments (self-explanatory code)
  • Proper null/undefined handling
  • No
    any
    types (use proper types)
🟡 Modern TypeScript Patterns:
  • Array methods used instead of manual loops
  • Arrow functions for callbacks
  • Optional chaining (?.) for safe property access
  • Nullish coalescing (??) for default values
  • Destructuring for cleaner code
  • Type guards for type narrowing
🟢 Cocos Creator Architecture:
  • Component lifecycle methods in correct order
  • onLoad() for initialization, start() for references
  • Event listeners registered in onEnable()
  • Event listeners unregistered in onDisable()
  • Resources released in onDestroy()
  • @property decorator used correctly
  • Required references validated (throw if null)
🔵 Playable Performance:
  • No allocations in update() loop
  • Sprite atlas used for DrawCall batching
  • GPU skinning enabled for skeletal animations
  • Expensive operations throttled (not every frame)
  • Object pooling for frequently created objects
  • Texture compression enabled
  • Bundle size <5MB target
  • DrawCall count <10 target
🔴 代码质量(首先检查):
  • tsconfig.json中启用TypeScript严格模式
  • ESLint规则通过(无错误)
  • 所有访问修饰符设置正确(public/private/protected)
  • 错误时抛出异常(无静默失败)
  • console.log已移除或包裹在CC_DEBUG中
  • 非重新赋值字段使用readonly
  • 常量使用const
  • 无行内注释(代码自解释)
  • 完善的null/undefined处理
  • 未使用
    any
    类型(使用正确类型)
🟡 现代TypeScript模式:
  • 使用数组方法而非手动循环
  • 回调函数使用箭头函数
  • 使用可选链操作符(?.)进行安全属性访问
  • 使用空值合并运算符(??)设置默认值
  • 使用解构赋值简化代码
  • 使用类型守卫进行类型收窄
🟢 Cocos Creator架构:
  • 组件生命周期方法顺序正确
  • onLoad()用于初始化,start()用于引用
  • 事件监听器在onEnable()中注册
  • 事件监听器在onDisable()中注销
  • 资源在onDestroy()中释放
  • @property装饰器使用正确
  • 必要引用已验证(为空时抛出异常)
🔵 可玩广告性能:
  • update()循环中无内存分配
  • 使用精灵图集进行DrawCall批处理
  • 骨骼动画启用GPU蒙皮
  • 耗时操作已节流(非每帧执行)
  • 频繁创建的对象使用对象池
  • 启用纹理压缩
  • 包体大小<5MB目标
  • DrawCall数量<10目标

Common Mistakes to Avoid

需避免的常见错误

❌ DON'T:

❌ 禁止:

  1. Ignore TypeScript strict mode → Enable "strict": true
  2. Silent error handling → Throw exceptions for errors
  3. Leave console.log in production → Remove or wrap in CC_DEBUG
  4. Skip access modifiers → Use public/private/protected
  5. Use
    any
    type
    → Define proper types and interfaces
  6. Add inline comments → Use descriptive names instead
  7. Skip event cleanup → Always unregister in onDisable/onDestroy
  8. Allocate in update() → Preallocate and reuse objects
  9. Forget sprite atlas → Use atlas for DrawCall batching
  10. Heavy logic in update() → Throttle expensive operations
  11. Skip null checks → Validate required references in onLoad
  12. Mutable @property fields → Use readonly when appropriate
  13. Manual loops over arrays → Use map/filter/reduce
  14. Ignore bundle size → Monitor and optimize (<5MB target)
  1. 忽略TypeScript严格模式 → 必须启用"strict": true
  2. 静默错误处理 → 错误时必须抛出异常
  3. 生产代码中保留console.log → 移除或包裹在CC_DEBUG中
  4. 跳过访问修饰符 → 必须使用public/private/protected
  5. 使用
    any
    类型
    → 定义正确的类型和接口
  6. 添加行内注释 → 改用具名化命名
  7. 跳过事件清理 → 必须在onDisable/onDestroy中注销事件
  8. 在update()中分配内存 → 预分配并复用对象
  9. 忘记使用精灵图集 → 必须使用图集进行DrawCall批处理
  10. 在update()中执行重逻辑 → 节流耗时操作
  11. 跳过空值检查 → 在onLoad()中验证必要引用
  12. 可变的@property字段 → 合适时使用readonly
  13. 手动循环数组 → 使用map/filter/reduce
  14. 忽略包体大小 → 监控并优化(目标<5MB)

✅ DO:

✅ 推荐:

  1. Enable TypeScript strict mode ("strict": true)
  2. Throw exceptions for errors (never silent failures)
  3. Use console.log for development only (remove in production)
  4. Use access modifiers (public/private/protected)
  5. Define proper types (avoid
    any
    )
  6. Use descriptive names (no inline comments)
  7. Always cleanup events (onDisable/onDestroy)
  8. Preallocate objects (reuse in update())
  9. Use sprite atlas (DrawCall batching)
  10. Throttle expensive operations (not every frame)
  11. Validate required references (throw in onLoad if null)
  12. Use readonly for @property (when appropriate)
  13. Use array methods (map/filter/reduce)
  14. Monitor bundle size (<5MB target for playables)
  1. 启用TypeScript严格模式("strict": true)
  2. 错误时抛出异常(绝不允许静默失败)
  3. console.log仅用于开发环境(生产构建中移除)
  4. 使用访问修饰符(public/private/protected)
  5. 定义正确的类型(避免
    any
  6. 使用具名化命名(无需行内注释)
  7. 始终清理事件(onDisable/onDestroy中)
  8. 预分配对象(在update()中复用)
  9. 使用精灵图集(DrawCall批处理)
  10. 节流耗时操作(非每帧执行)
  11. 验证必要引用(onLoad()中为空则抛出异常)
  12. 合适时为@property使用readonly
  13. 使用数组方法(map/filter/reduce)
  14. 监控包体大小(可玩广告目标<5MB)

Review Severity Levels

审查严重程度等级

🔴 Critical (Must Fix)

🔴 严重(必须修复)

  • TypeScript strict mode disabled - Must enable "strict": true
  • Silent error handling - Must throw exceptions for errors
  • console.log in production code - Remove or wrap in CC_DEBUG
  • Missing access modifiers - All members must have modifiers
  • Using
    any
    type without justification
    - Define proper types
  • Inline comments instead of descriptive names - Rename and remove comments
  • Event listeners not cleaned up - Memory leak, must unregister
  • Missing required reference validation - Must throw in onLoad if null
  • Allocations in update() loop - Performance critical, must preallocate
  • No sprite atlas for multiple sprites - DrawCall explosion, must use atlas
  • Bundle size >5MB - Exceeds playable limit, must optimize
  • TypeScript严格模式未启用 - 必须设置"strict": true
  • 静默错误处理 - 必须抛出异常
  • 生产代码中存在console.log - 移除或包裹在CC_DEBUG中
  • 缺失访问修饰符 - 所有成员必须添加修饰符
  • 无正当理由使用
    any
    类型
    - 定义正确的类型
  • 使用行内注释而非具名化命名 - 重命名并移除注释
  • 事件监听器未清理 - 内存泄漏,必须注销
  • 缺失必要引用验证 - onLoad()中为空则必须抛出异常
  • update()循环中存在内存分配 - 性能关键,必须预分配
  • 多精灵未使用精灵图集 - DrawCall激增,必须使用图集
  • 包体大小>5MB - 超出可玩广告限制,必须优化

🟡 Important (Should Fix)

🟡 重要(应该修复)

  • Missing readonly on @property fields - Should be readonly when not reassigned
  • Missing const for constants - Should use const instead of let
  • Manual loops instead of array methods - Should use map/filter/reduce
  • Missing optional chaining - Should use ?. for safe access
  • Missing nullish coalescing - Should use ?? for default values
  • Heavy logic in update() - Should throttle expensive operations
  • No object pooling for frequent allocations - Should implement pooling
  • Texture compression not enabled - Should enable for smaller bundle
  • DrawCall count >10 - Should optimize batching
  • @property字段未使用readonly - 无需重新赋值时应使用readonly
  • 常量未使用const - 应使用const而非let
  • 手动循环而非数组方法 - 应使用map/filter/reduce
  • 未使用可选链操作符 - 应使用?.进行安全访问
  • 未使用空值合并运算符 - 应使用??设置默认值
  • update()中执行重逻辑 - 应节流耗时操作
  • 频繁分配的对象未使用对象池 - 应实现对象池
  • 未启用纹理压缩 - 应启用以减小包体
  • DrawCall数量>10 - 应优化批处理

🟢 Nice to Have (Suggestion)

🟢 建议(可选优化)

  • Could use arrow function for callback
  • Could destructure for cleaner code
  • Could use type guard for type safety
  • Could improve naming for clarity
  • Could add interface for better typing
  • Could optimize algorithm for better performance
  • 可使用箭头函数作为回调
  • 可使用解构赋值简化代码
  • 可使用类型守卫保证类型安全
  • 可优化命名以提升清晰度
  • 可添加接口以提升类型化
  • 可优化算法以提升性能

Detailed References

详细参考文档

TypeScript Language Standards

TypeScript语言标准

  • Quality & Hygiene - Strict mode, ESLint, access modifiers, error handling
  • Modern TypeScript - Array methods, optional chaining, type guards, utility types
  • Performance - Update loop optimization, zero allocations, caching
  • 质量与规范 - 严格模式、ESLint、访问修饰符、错误处理
  • 现代TypeScript - 数组方法、可选链、类型守卫、工具类型
  • 性能优化 - Update循环优化、零内存分配、缓存

Cocos Creator Framework

Cocos Creator框架

  • Component System - EC system, lifecycle methods, @property decorator
  • Event Patterns - EventDispatcher, Node events, subscription cleanup
  • Playable Optimization - DrawCall batching, sprite atlas, GPU skinning, resource pooling
  • Size Optimization - Bundle size reduction, texture compression, build optimization
  • 组件系统 - EC系统、生命周期方法、@property装饰器
  • 事件模式 - EventDispatcher、节点事件、订阅清理
  • 可玩广告优化 - DrawCall批处理、精灵图集、GPU蒙皮、对象池
  • 大小优化 - 包体大小缩减、纹理压缩、构建优化

Code Review

代码审查

  • Architecture Review - Component violations, lifecycle errors, event leaks
  • Quality Review - TypeScript quality issues, access modifiers, error handling
  • Performance Review - Playable-specific performance problems, DrawCalls, allocations
  • 架构审查 - 组件违规、生命周期错误、事件泄漏
  • 质量审查 - TypeScript质量问题、访问修饰符、错误处理
  • 性能审查 - 可玩广告特定性能问题、DrawCall、内存分配

Summary

总结

This skill provides comprehensive Cocos Creator development standards for TheOne Studio's playable ads team:
  • TypeScript Excellence: Strict mode, modern patterns, type safety
  • Cocos Architecture: Component lifecycle, event patterns, resource management
  • Playable Performance: DrawCall batching, GPU skinning, <5MB bundles
  • Code Quality: Enforced quality, hygiene, and performance rules
Use the Quick Reference Guide above to navigate to the specific pattern you need.
本技能为TheOne Studio的可玩广告团队提供全面的Cocos Creator开发标准:
  • TypeScript卓越性:严格模式、现代模式、类型安全
  • Cocos架构:组件生命周期、事件模式、资源管理
  • 可玩广告性能:DrawCall批处理、GPU蒙皮、<5MB包体
  • 代码质量:强制执行质量、规范与性能规则
使用上方的快速参考指南导航至你需要的特定模式。