博客文章
Cocos 游戏项目的 Claude Code 配置实践(4):Skills
CLAUDE.md 和 Rules 是知识,Skills 是流程。分享游戏项目里的四个 Skills:从 FGUI XML 生成窗口代码、ECS 组件/系统脚手架、项目全貌扫描,以及如何判断该不该封装成 Skill 和踩坑经验。
Cocos 游戏项目的 Claude Code 配置实践(4):Skills
系列文章目录:总览 → CLAUDE.md → Rules → [Skills] → MCP → Hooks → Agents
朋友们大家好,我是 bit老宫 呀,一个拥有12年一线开发经验的CocosCreator游戏开发者,代表作 《比特小队》 《宫爆老奶奶家族篇》
前两篇聊了 CLAUDE.md 和 Rules,它们的共同点是「告诉 AI 规范」——AI 知道了该怎么做,但还是要靠你的指令触发。
Skills 不一样。它把一套完整的操作流程封装成一个命令,你喊一声 /create-window ShopWindow Shop,AI 自己读 FGUI 工程文件、提取节点结构、按规范生成代码、保存到正确路径——全套走完,你只需要验收结果。
Skills 和 CLAUDE.md 的本质区别
CLAUDE.md 和 Rules 是知识——告诉 AI「应该怎么做」。 Skills 是流程——告诉 AI「按这些步骤执行」。
打个比方:CLAUDE.md 是给员工看的规范手册,Skills 是给员工看的操作手册。前者建立认知,后者按步骤执行。
Skill 文件长什么样
放在 .claude/skills/<skill-name>/SKILL.md,头部是 YAML 配置,正文是执行步骤。以我项目里的 /create-window 为例:
---
name: create-window
description: 创建符合项目规范的 UI 窗口类,自动读取 FGUI 工程 XML 获取节点结构
user-invocable: true
argument-hint: [窗口名] [FGUI包名] [窗口组名]
allowed-tools: Read(*), Write(*), Glob(*), Grep(*)
---
# 创建 UI 窗口
## 参数解析
- $ARGUMENTS[0] = 窗口类名(如 ShopWindow)
- $ARGUMENTS[1] = FGUI 包名(如 Shop)
- $ARGUMENTS[2] = 窗口组名(默认 "Window")
## 执行步骤
### 1. 读取 FGUI 节点结构
读取 XML 文件:FguiCreator3.8/assets/$ARGUMENTS[1]/$ARGUMENTS[0].xml
从 <displayList> 中提取所有节点的 name 和类型……
### 2. 参考现有代码风格
读取 header.ts 和 1-2 个现有 Window 文件……
### 3. 生成窗口代码
(完整的代码模板和映射规则……)
几个关键配置项:
user-invocable: true:允许用户在对话中直接用/create-window触发argument-hint:提示用户需要传什么参数allowed-tools:限制 Skill 执行时可以使用的工具(安全约束)
游戏项目里的四个 Skills
/create-window — 从 FGUI XML 生成窗口代码
这是使用频率最高的 Skill。FairyGUI 的界面结构存在 XML 文件里,每个 UI 窗口的节点名称、类型(按钮、文本、图片、组件容器……)都在 XML 的 <displayList> 节点中。
以前手动创建一个窗口的流程:
- 打开 FGUI 工程,找到对应的 XML 文件
- 逐个看节点名和类型
- 对照类型映射表(
<text>→FGUI.GTextField、<component>+<Button/>→FGUI.GButton……) - 手写 Window 子类,包括
@uiprop属性绑定、@uiclick回调、生命周期方法 - 反复检查有没有写错类型或遗漏节点
配置 Skill 之后:
/create-window ShopWindow Shop
30 秒后,AI 生成了完整的窗口代码:
import { UI, FGUI } from "../header";
const { uiclass, uiclick, uiprop } = UI._uidecorator;
@uiclass("Window", "Shop", "ShopWindow")
export class ShopWindow extends UI.Window {
@uiprop private _btn_close: FGUI.GButton;
@uiprop private _btn_buy: FGUI.GButton;
@uiprop private _txt_title: FGUI.GTextField;
@uiprop private _txt_price: FGUI.GTextField;
@uiprop private _list_items: FGUI.GComponent;
protected onInit(): void {
this.adapterType = UI.AdapterType.Bang;
this.type = UI.WindowType.Normal;
}
protected onShow(_userdata?: unknown): void {
}
protected onClose(): void {
}
@uiclick
private onCloseSelf(): void {
this.removeSelf();
}
@uiclick
private onBuy(): void {
}
}
节点名称、类型映射、装饰器写法、生命周期框架——全部自动生成,符合项目规范。原本 10 分钟的活儿,30 秒搞定。
/create-component — ECS 组件脚手架
ECS 组件有严格的写法规范:必须继承 ecs.Component、使用 @ecsclass 和 @ecsprop 装饰器、必须实现 reset() 方法……每次手写都要对照规范检查。
/create-component Velocity "速度组件" basics
AI 会先确认需要哪些属性,然后生成标准的组件代码,自动放到正确的目录(assets/script/ecs/component/basics/)。
标记组件更简单:
/create-component TagEnemy "敌人标记" mark
生成一个无属性、空 reset 的标记组件,放到 mark/ 目录。
/create-system — ECS 系统脚手架
和组件类似,系统也有固定的写法模式:继承 ecs.System、onInit() 配置 matcher、update(dt) 遍历实体。
/create-system MoveSystem "移动系统" basics
AI 会询问需要匹配哪些组件(allOf / anyOf / excludeOf),然后生成完整的系统骨架。
/project-info — 一句话查项目全貌
/project-info all
AI 扫描整个项目,以表格形式输出所有窗口、ECS 组件、系统、实体配置。开始新功能前先跑一遍,避免重复造轮子,也帮助理解项目现状。
如何判断该不该封装成 Skill
不是所有重复任务都需要 Skill。我的判断标准:
- 频率:这个任务一周会做几次?偶尔一次的不值得
- 步骤固定:流程是否固定?每次都是相同的步骤?需要灵活判断的更适合 Agent
- 容易出错:手动做是否容易遗漏或写错?比如节点类型映射,手写就是容易错
- AI 需要解释:每次触发都要给 AI 解释一遍流程?那就该固化了
满足 2-3 条以上,就值得封装。
踩坑经验
坑一:步骤描述不够具体
早期版本的 /create-window 只写了「读取 XML 并生成代码」,AI 每次生成的代码风格不一致——有时候用 private,有时候不写修饰符;有时候加 _ 前缀,有时候不加。
解决方法:在 Skill 里直接给出完整的代码模板和映射规则表,步骤越具体,执行结果越稳定。现在的 SKILL.md 里有完整的 XML → TypeScript 类型映射表,AI 照着表格映射,不会出错。
坑二:没有参考现有代码
AI 生成的代码风格和项目里现有代码不一致。比如 import 写法、装饰器解构方式、空行和缩进风格……
解决方法:在 Skill 步骤里加一步「读取 1-2 个现有同类文件参考代码风格」。AI 会自动对齐现有代码的写法,生成的代码和手写的看不出区别。
坑三:权限太宽
allowed-tools 开太大(比如允许 Bash),Skill 执行时可能跑出意料之外的命令。Skill 只需要读文件和写文件,限制在 Read(*), Write(*), Glob(*), Grep(*) 足够了。
效果
引入 Skills 后,我发现一个额外的好处:团队里任何开发者调用同一个 Skill,得到的代码结构完全一致。这对团队协作尤其有价值——不再是「每个人和 AI 聊出来的代码不一样」,而是标准化的输出。
下一篇
Skills 解决了重复性任务的自动化问题。但还有一类问题 Skills 和 Rules 都解决不了:AI 不认识你的私有框架 API。下一篇聊 MCP——给 AI 挂载一个可以查询的知识库,让它不再凭印象猜 API。