Cocos 游戏项目的 Claude Code 配置实践(3):Rules

系列文章目录:总览 → CLAUDE.md → [Rules] → Skills → MCP → Hooks → Agents

朋友们大家好,我是 bit老宫 呀,一个拥有12年一线开发经验的CocosCreator游戏开发者,代表作 《比特小队》 《宫爆老奶奶家族篇》

上一篇聊了 CLAUDE.md 作为项目说明书的作用。但用着用着你会遇到一个问题:项目规范越写越多,CLAUDE.md 膨胀得装不下了。更关键的是,很多规范只在特定场景下才需要——写 ECS 代码时需要 ECS 规范,写 UI 代码时需要 UI 规范,两者放在一起不仅浪费上下文,还容易让 AI 搞混。

Rules 就是为了解决这个问题。

工作原理

Rules 文件放在 .claude/rules/ 目录下。每个文件头部用 YAML frontmatter 声明触发路径:

---
paths:
  - "assets/script/ecs/**/*.ts"
---
# ECS 工作流规范
(具体规则内容……)

paths 使用 glob 模式匹配。当 AI 编辑或读取匹配路径的文件时,这份规则自动注入到当前对话的上下文里。不匹配就不加载,零干扰。

几个关键细节:

  • 支持多路径:一份 Rules 可以匹配多个目录
  • 自动加载:不需要手动引用,匹配即生效
  • 不设 paths 则全局生效:不写 frontmatter 的 Rules 文件等同于 CLAUDE.md 的补充

一份完整的 Rules 长什么样

以我项目里的 ecs-workflow.md 为例,这是我迭代最多的一份 Rules:

---
paths:
  - "assets/script/ecs/**/*.ts"
---

# ECS 工作流

## 正确的开发顺序
1. 先写 Component 组件代码(定义数据结构)
2. 再写 System 系统代码(定义处理逻辑)
3. 新系统必须在 `ECSHelper.register()` 中注册到对应 SystemGroup
4. 最后在 Cocos 插件中配置实体(组合组件),由开发者操作

## 组件规范
- 继承 `ecs.Component`,使用 `@ecsclass(名称, { describe: 描述 })` 装饰
- 属性使用 `@ecsprop({ type, defaultValue })` 装饰
- 必须实现 `reset()` 方法,将所有属性恢复到默认值
- 标记组件(Tag)无属性,`reset()` 为空实现
- 组件只存储数据,禁止包含业务逻辑
- 装饰器解构:`const { ecsclass, ecsprop } = ecs._ecsdecorator`

## 系统规范
- 继承 `ecs.System`,使用 `@ecsystem(名称, { describe: 描述 })` 装饰
-`onInit()` 中配置 matcher:
  - `allOf(Comp1, Comp2)` — 必须包含的组件
  - `anyOf(Comp1, Comp2)` — 至少包含一个
  - `excludeOf(Comp)` — 排除包含此组件的实体
  - `optionalOf(Comp)` — 可选组件(iterate 中可能为 null)
-`update(dt)` 中使用 `query.iterate1/2/3/4()` 遍历实体
- 系统只包含逻辑,禁止存储持久状态(单例数据用单例组件)
- 装饰器解构:`const { ecsystem } = ecs._ecsdecorator`

## 实体配置
- 位置:`extensions-config/entity/<entityName>.json`
- 配置描述实体包含哪些组件及默认属性值
- 可直接修改,修改后需通过编辑器重新导出配置文件
- 用途:了解已有实体的组件组合,帮助理解业务上下文

## 文件组织
- 组件放 `assets/script/ecs/component/` 下按类别分子目录
  - `basics/` — 基础通用组件(Position, Speed, Render 等)
  - `configure/` — 配置型组件(Shape, Asset 等)
  - `header/` — 枚举/类型定义
  - `mark/` — 标记组件(TagHero, TagEnemy 等)
  - `singleton/` — 单例组件
- 系统放 `assets/script/ecs/system/` 下按类别分子目录
  - `basics/` — 基础系统(Move, Render, LifeTime 等)
  - `generate/` — 初始化/生成系统
  - `debug/` — 调试系统

## import 风格
- 使用 header.ts:`import { ecs } from "../../../header"`
- 组件间引用使用相对路径

50 多行,涵盖了开发顺序、代码规范、文件组织——所有写 ECS 代码需要知道的约定,集中在一个地方。

我的项目里有哪些 Rules

目前拆了 9 份,按照模块对应:

规则文件 触发路径 核心内容
ecs-workflow.md script/ecs/**/*.ts 组件/系统开发流程和规范
ui-module.md script/UI/**/*.ts Window 生命周期、WindowType、窗口操作 API
fgui-workflow.md script/**/*.ts FGUI XML 节点结构读取、类型映射表
event-module.md script/**/*.ts GlobalEvent 用法、销毁清理监听
core-module.md script/**/*.ts GlobalTimer、Platform、Screen、日志
assets-module.md script/**/*.ts AssetLoader、AssetPool 资源管理
net-module.md script/**/*.ts HttpManager、Socket 网络请求
behaviortree-module.md script/**/*.ts 行为树节点装饰器、黑板数据
code-style.md script/**/*.ts 命名规范、代码质量规则

你会注意到 ecs-workflow.md 的路径更窄(只匹配 ecs/ 目录),而其他模块的路径基本都是 script/**/*.ts。这是因为 ECS 规范只在写 ECS 代码时需要,但 事件、资源这些模块的 API 在任何脚本文件里都可能用到。

拆分策略:什么粒度合适?

我的拆分原则

  1. 按框架模块拆:每个模块一份 Rules,对应一组 API 和规范
  2. 通用规范独立:代码风格(命名、格式、质量)单独一份,所有 .ts 文件共享
  3. 够用就行:不需要拆得太细。一个模块的规范通常 30-60 行,合并在一份文件里完全可以

关键判断标准:如果两套规范从来不会同时需要,就拆开;如果经常一起使用,就合在一起。

与 CLAUDE.md 的分工

这两者的边界有时候不那么清晰,我的划分方式是:

内容 放哪里 理由
引擎版本约束 CLAUDE.md 全局有效,任何代码都要遵守
框架模块映射表 CLAUDE.md 全局索引,帮 AI 找到对应的 Rules
工作流约束(先计划后执行) CLAUDE.md 全局行为准则
项目目录结构 CLAUDE.md 全局信息
ECS 组件/系统写法 Rules 只在写 ECS 代码时需要
Window 生命周期 Rules 只在写 UI 代码时需要
GlobalEvent API Rules 只在写事件代码时需要
命名规范、代码质量 Rules 只在写 .ts 代码时需要

简单说:CLAUDE.md 写「what」和「why」(项目用什么、为什么这样做),Rules 写「how」(具体怎么写代码)。

踩坑经验

坑一:paths 写错导致规则不生效

最常见的问题。我早期写 paths: ["ecs/**/*.ts"],但实际文件在 assets/script/ecs/ 下。glob 模式是从项目根目录匹配的,必须写完整路径:"assets/script/ecs/**/*.ts"

排查方法:在对话里问 AI「你现在加载了哪些 Rules?」或者让 AI 读一个匹配路径的文件,看它的回答是否体现了 Rules 里的知识。

坑二:Rules 之间信息重复

初期我在 ui-module.mdfgui-workflow.md 里都写了节点类型映射表,后来修改了一处忘了改另一处,AI 收到矛盾信息。同一条规范只能出现在一个地方,其他地方引用即可。

坑三:Rules 过长

一份 Rules 超过 100 行就要警惕了。我把 code-style.md 写到了 120 行,发现 AI 对后半段的规范遵守度明显下降。拆成两份或精简内容后恢复正常。

效果

配置前:写 ECS 系统时,每次都要手动告诉 AI「组件只存数据不能有逻辑」「系统用 allOf/anyOf 配置 matcher」「新文件放 system/basics/ 目录」……每次都是同样的话。

配置后:打开 ECS 文件,AI 自动知道整套规范。组件和系统的代码结构一次到位,目录分类也正确。

下一篇

CLAUDE.md + Rules 解决了「AI 不知道项目规范」的问题。但有些任务不是靠规范就能解决的——它们是固定流程的重复性工作,每次都要从头解释一遍。下一篇聊 Skills——把这些重复动作封装成一句命令。