# 项目开发规范(AI 与人工必读) > 更新日期:2026-08-17 > 适用范围:本仓库全部 TypeScript / 业务逻辑新增与修改 > Cursor 持久规则:`.cursor/rules/dev-standards.mdc` 本文档定义 **AI 智能体生成代码** 与 **人工协作开发** 的强制标准。违反项应在 Code Review 与合并前纠正。 --- ## 1. 工程素养与全局视角 ### 1.1 经验水准 以 **二十年资深程序员** 的标准审视每一行代码:熟悉常见技术实现、设计模式、引擎机制与平台差异,不写出「只会堆代码」的解法。 ### 1.2 全局优先(含临时修 Bug) **任何改动**——包括一行临时修 Bug——都必须从 **全局** 出发,综合评估: | 维度 | 要求 | |------|------| | 架构性 | 是否符合分层(MX 框架 / 业务 / UI),是否破坏模块边界 | | 可复用性 | 是否可沉淀为通用能力,避免复制粘贴 | | 可扩展性 | 后续需求是否只需扩展而非推翻 | | 高可靠性 | 异常路径是否可控,状态是否一致 | | 安全性 | 输入、存档、网络、平台 API 是否安全使用 | 禁止「只改眼前这一处、不管上下游」的局部补丁式屎山。 ### 1.3 长期记忆与整体分析 - 对话可能很长,**不能仅依赖当前会话上下文**;须结合 `docs/` 文档、架构分层与已有模块做 **整体分析**。 - 新会话开始前应查阅:`项目说明.md`、`项目分析报告.md`、相关 `需求-*` / `方案-*`。 - 架构级决策写入 `docs/`,形成项目 **长期记忆**,避免「聊着聊着忘了」或「新开会话全忘」。 --- ## 2. 面向对象与代码组织 ### 2.1 OOP 为默认范式 - 必须基于 **面向对象** 开发,运用软件工程中的封装、抽象、单一职责、依赖倒置等原则。 - **任何功能模块** 使用类 + 接口组织;逻辑归属清晰,不散落。 ### 2.2 禁止全局函数 - **业务逻辑** 必须在 **接口或类** 中实现。 - **禁止** 新增裸全局函数承载业务逻辑。 - 例外(已存在、勿再扩散): - 引擎生命周期组件(`Component` 子类) - 框架级单例入口(如 `gg`) - 纯类型/常量模块的导出(无运行时逻辑) ### 2.3 文件与脚本粒度 - **禁止** 为一个小需求随意新增 TS 文件。 - 同类 **数据结构、接口定义** 合并到同一文件(如 `*Types.ts`、`*Defs.ts`)。 - 新增文件须有明确模块边界理由,并在文档或 PR 说明中可解释。 ### 2.4 命名 - 接口、枚举、类、字段、函数名:**简化驼峰**,简洁易懂,**禁止过长名称**。 - 示例:`BattleFacade`(可)、`BattleSessionRuntimeFacadeManager`(过长,避免)。 --- ## 3. 代码质量:简洁、无屎山、无擅自兜底 ### 3.1 简洁可读 - 完全杜绝屎山:短函数、清晰分支、少嵌套;能自解释的代码优先于冗长注释。 - **通用框架代码**(`assets/mx/`)中 **不写业务逻辑注释**;框架层仅保留必要的模块/契约说明。 ### 3.2 禁止擅自兜底 - **坚决禁止** 任何形式的静默兜底(默认值掩盖错误、吞异常、`??` 掩盖配表缺失、空实现假装成功等)。 - **允许**:显式 **容错警告**(`console.warn` / 受控日志 / 上报),让问题 **暴露** 给开发者或监控。 - 数据缺失、配表错误、资源加载失败等:**报错或中止当前流程**,由上游或策划修复,不得 AI 自行「猜一个能跑的值」。 ### 3.3 变量与常量 - 实现功能时 **不随意新增** 变量/常量;能复用现有状态、参数、类字段的则复用。 - 新增须有必要性(生命周期、可读性、性能分帧等),避免无意义中间变量堆砌。 --- ## 4. 文档注释规范 ### 4.1 必须写文档注释的符号 以下 **全部** 须有标准 JSDoc 风格 **文档注释**(`/** ... */`),简洁明了: - 数据结构定义(`interface`、`type` 别名若表达业务含义) - 类 - 接口 - 枚举及 **每一个枚举项** - 字段(`interface` / 类 public 成员) - 函数 / 方法(含参数与返回值说明,若含义不直观) ### 4.2 注释风格 ```typescript /** 战斗会话对外门面,项目层唯一入口 */ export class BattleFacade { /** 当前活跃会话;无战斗时为 null */ private _session: BattleSession | null = null; /** * 部署塔单位 * @param weapon1Id Weapon1 表 id * @param row 逻辑行 0~11 * @param col 逻辑列 0~9 */ deploy(weapon1Id: number, row: number, col: number): void { } } /** 章节难度 */ export enum ChapterDiff { /** 普通 */ Normal = 2, } ``` - 不写废话注释(`// 赋值`);不写与代码矛盾的注释。 - **框架通用代码** 不写逐步逻辑注释;业务复杂流程可在 **业务层** 用简短注释说明非显而易见的规则。 --- ## 5. 函数与语法约束 | 规则 | 说明 | |------|------| | 参数不换行 | 函数形参列表写在 **同一行**;过长时优先简化命名或减少参数,而非拆行 | | 禁止函数内定义函数 | 不在方法体内 `function foo()` 或箭头函数承载可复用逻辑;提取为类私有方法 | | 尽量避免闭包 | 回调、延迟逻辑定义为 **类方法**,显式 `bind` 或使用箭头类字段(注意 `onDestroy` 解绑) | | 回调归属 | 事件、动画、加载完成等回调写在类中,生命周期内配对注册/注销 | --- ## 6. TypeScript 与 Cocos 平台约束 ### 6.1 ES 版本与语法 - 遵循 Cocos Creator 推荐的 **ES 版本**(以项目 `tsconfig` 与引擎文档为准)。 - **禁止使用** 高风险、小游戏环境 **不稳定** 的语法与内置类型,例如: - **`Set` / `Map`**(部分真机/小游戏解析或序列化异常;用数组 + 显式去重或项目内 `MembershipSet` 等等价结构) - **禁止** 对 `Map`/`Set` 迭代器做展开或 `Array.from`:`[...map.keys()]`、`[...map.values()]`、`[...map.entries()]`、`[...map]`、`[...set]`、`Array.from(map.keys())`。web-mobile 会编成 `[].concat(iterator)`,得到空对象,随后 `.map` 崩。收数组用 `mapKeysToArray` / `mapValuesToArray` / `membershipToArray`;遍历用 `forEach`。 - 过度依赖新特性而未经平台验证的 API ### 6.2 Cocos Creator 官方文档 - 调用引擎能力(节点、组件、资源、`assetManager`、`director`、动画、物理等)时 **严格遵守官方文档**。 - 不臆造 API;不依赖未文档化行为;版本差异以 **3.8.8** 为准。 --- ## 7. 需求边界(禁止擅自发挥) | 情况 | 行为 | |------|------| | 需求不明确 | **必须询问用户** 并确认,不得猜测实现 | | 用户未授权「自行发挥」 | **禁止** 自行扩展玩法、数值、交互 | | 行业惯例 / 通用默认 | 允许(例:未规定飞行特效细节时,可自行设计「酷炫」表现) | | 策划数值、流程、文案 | **禁止** AI 擅自更改;有疑问先问 | --- ## 8. 性能与帧循环 除架构要求外,必须考虑 **运行时性能**: - **时间复杂度 / 空间复杂度**:热路径(`update`、战斗 tick、列表刷新)避免 O(n²) 与无谓分配。 - **帧循环**:能 **分帧** 的必须分帧(`FrameFlowHost`、分帧加载、延迟初始化);能 **延迟** 的延迟(非关键路径不要阻塞首帧)。 - 避免在 `update` 内创建对象、查表、字符串拼接;缓存、池化、脏标记优先。 - 与 `LoadScheduler`、`ResourcePhaseGate` 等资源策略对齐,不在错误阶段猛加载。 --- ## 9. 动画与异步生命周期 适用于 **Tween、插值、Spine、程序 Animation** 等一切动画: - 视为 **异步逻辑**:开始、停止、完成、被覆盖、节点销毁须成对处理。 - **必须** 处理:停止动画、清除回调、组件 `onDestroy` 时取消未完成动画。 - 禁止:节点已销毁仍执行 tween 回调、重复注册未清理的 `complete` 导致崩溃或逻辑错乱。 - 动画与战斗暂停、UI 遮挡、场景切换的交互须明确(参考 `BattleUiPauseGate` 等现有门闩)。 --- ## 10. 资源加载、使用与释放 资源相关代码为 **高危区**,须深度理解引擎资源机制与各真机环境: | 要求 | 说明 | |------|------| | 加载 | 明确 bundle、路径、阶段;失败 **暴露错误**,不静默跳过 | | 使用 | 持有引用期间节点有效;异步回调前校验 `isValid(node)` | | 释放 | 与 `BundleLifecycle`、`gg.res` 策略一致;不提前释放仍被渲染/引用的资源 | | 异常操作 | 考虑玩家快速切换界面、断网、重复点击、战斗中途退出 | | 禁止 | **资源已释放仍参与渲染** 导致的崩溃(空纹理、无效 SpriteFrame 等) | 参考模块:`AssetService`、`BundleLifecycle`、`RuntimeLoadingGate`、`BattleBackgroundLoadGate`。 --- ## 11. 内存、复用与对象池 实现代码时 **必须考虑内存**,不能完全不顾内存占用与 GC 压力。 ### 11.1 复用优先 - 能复用的对象、数组、临时结构 **尽量复用**,避免热路径频繁 `new`。 - 与第 8 节性能要求一致:分帧、池化、脏标记、减少短命对象。 ### 11.2 对象池 | 要求 | 说明 | |------|------| | 正确使用 | 出池用于显示/逻辑,用毕 **归还**;禁止泄漏(借出未还、重复归还) | | 状态初始化 | 复用前 **深度分析** 该对象的全部使用方与字段含义;`onGet` / `reset` / `clear` 须 **完整重置状态**,不得残留上一轮数据 | | 禁止新 Bug | 不得因池化引入逻辑错误(脏数据、错误 parent、未解绑事件、动画未停) | | 与释放平衡 | 池化是为复用,不是无限囤积;池容量与释放策略须符合 `MemoryProfile` 档位 | 对象池适用:子弹、飘字、列表 Item、临时 Node 包装等高频创建/销毁对象。 ### 11.3 释放字段与引用 - 除对象池外,**可释放** 的资源引用、大数组、缓存字段、事件监听、定时器,在生命周期结束时应 **显式释放或置空**。 - 释放前须分析:**是否仍被异步回调、动画、其他模块持有**。 - **禁止** 因过早释放引入崩溃或逻辑错误(与第 10 节资源释放原则一致:释放须安全,不释放须可解释)。 ### 11.4 自检要点 - [ ] 出池对象所有业务字段已重置? - [ ] 事件、 tween、Spine 监听已解绑? - [ ] 节点 parent、active、组件引用已恢复默认? - [ ] 归还后无外部仍持有该实例的强引用? --- ## 12. 与现有架构的关系 | 层级 | 路径 | 新代码原则 | |------|------|------------| | MX 框架 | `assets/mx/` | 无业务逻辑;可复用能力;不加业务注释 | | 业务 | `assets/script/` | 玩法、配表、SDK 适配 | | UI | `assets/script/ui/` | 展示与交互;通过门面访问战斗/数据 | 老项目复制代码 **不完全符合** 本规范;**新写与改动触及的代码** 须向本规范收敛,大规模遗留清理按 [`遗留代码收敛方案.md`](./遗留代码收敛方案.md) 与 `docs/需求-*` 排期。 ### 遗留代码策略(摘要) - **禁止** 无需求驱动的全库规范重构(易回归且可能重构即将删除的模块)。 - **新代码** 与 **本次修改触及的文件** 必须遵规范。 - 全库收敛分阶段见 `遗留代码收敛方案.md`。 --- ## 13. 自检清单(提交前) - [ ] 是否从全局/架构评估过,而非只改一处? - [ ] 逻辑是否在类/接口中,无新增全局业务函数? - [ ] 是否避免多余文件、多余变量? - [ ] 接口/类/枚举/枚举项/字段/函数均有文档注释? - [ ] 函数参数未换行?函数内无嵌套函数定义? - [ ] 无静默兜底?问题是否暴露? - [ ] 未使用 `Set`/`Map` 等不稳定结构(新代码)? - [ ] 动画与资源:销毁/取消/释放是否完整? - [ ] 对象池:出池重置完整、归还无泄漏、无脏状态? - [ ] 可释放字段/引用:生命周期结束是否安全释放,且未过早释放? - [ ] 热路径是否考虑分帧、内存与性能? - [ ] 需求是否经用户确认,未擅自改策划? --- ## 14. 相关文档 - [项目说明.md](./项目说明.md) — 目录约定与项目背景 - [项目分析报告.md](./项目分析报告.md) — 代码基线架构 - [性能打点说明.md](./性能打点说明.md) — 性能打点(若沿用)