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> 节点中。

以前手动创建一个窗口的流程:

  1. 打开 FGUI 工程,找到对应的 XML 文件
  2. 逐个看节点名和类型
  3. 对照类型映射表(<text>FGUI.GTextField<component> + <Button/>FGUI.GButton……)
  4. 手写 Window 子类,包括 @uiprop 属性绑定、@uiclick 回调、生命周期方法
  5. 反复检查有没有写错类型或遗漏节点

配置 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.SystemonInit() 配置 matcher、update(dt) 遍历实体。

/create-system MoveSystem "移动系统" basics

AI 会询问需要匹配哪些组件(allOf / anyOf / excludeOf),然后生成完整的系统骨架。

/project-info — 一句话查项目全貌

/project-info all

AI 扫描整个项目,以表格形式输出所有窗口、ECS 组件、系统、实体配置。开始新功能前先跑一遍,避免重复造轮子,也帮助理解项目现状。

如何判断该不该封装成 Skill

不是所有重复任务都需要 Skill。我的判断标准:

  1. 频率:这个任务一周会做几次?偶尔一次的不值得
  2. 步骤固定:流程是否固定?每次都是相同的步骤?需要灵活判断的更适合 Agent
  3. 容易出错:手动做是否容易遗漏或写错?比如节点类型映射,手写就是容易错
  4. 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。