godot-tdd

SKILL.md

Godot TDD 开发流程 Skill

概述

本 Skill 提供 Godot TDD(测试驱动开发)流程的总控能力,协调 godot-designgodot-devgodot-testgodot-verify 四个子 Skill 完成完整的开发循环。

适用场景

  • 需要遵循 TDD 流程开发游戏逻辑
  • 每个修改都需要代码质量检查
  • 需要明确的流程检查点确保质量
  • 团队协作时需要统一的开发规范

使用方式

开始 TDD 流程

{
  "skill": "godot-tdd",
  "action": "start",
  "feature": "功能名称",
  "description": "功能详细描述"
}

流程控制

{
  "skill": "godot-tdd",
  "action": "next_phase"
}

TDD 流程

┌─────────────────────────────────────────────────────────┐
│                    godot-tdd (总控)                      │
├─────────────────────────────────────────────────────────┤
│  phase 1: design    → godot-design (接口规范)            │
│       ↓                                                   │
│  phase 2: test      → godot-test (GUT 框架使用)          │
│       ↓                                                   │
│  phase 3: implement → godot-dev                          │
│       ↓                                                   │
│  phase 4: verify    → godot-verify (lint/format)         │
│       ↓                                                   │
│  phase 5: run_test  → godot-test (验证测试通过)          │
│       ↓                                                   │
│  循环直到功能完成                                         │
└─────────────────────────────────────────────────────────┘

详细流程

Phase 1: 接口设计 (godot-design)

目标:定义清晰的接口规范

操作

  1. 使用 godot-design 定义:
    • 公开方法签名(带类型注解)
    • 状态查询方法(供测试断言)
    • 信号定义(事件解耦)
    • 错误处理方式

检查点

  • 符合 Godot 类系统规则
  • 单一职责
  • 有测试友好的查询方法

示例

class_name PlayerController extends Node

# 状态查询(供测试使用)
func get_health() -> int: ...
func is_alive() -> bool: ...

# 动作方法
func take_damage(amount: int) -> void: ...

# 信号
signal health_changed(new_health: int)
signal died()

Phase 2: 测试开发 (godot-test)

目标:编写失败的测试用例

操作

  1. 使用 godot-test 编写测试:
    • 测试文件:test_<目标类>.gd
    • 测试方法:test_<方法>_<场景>_<预期>
    • 继承 GutTest

检查点

  • 测试能运行
  • 测试失败(预期行为,尚未实现)

示例

extends GutTest

func test_player_take_damage_reduces_health():
    var sut = Player.new()
    sut.take_damage(10)
    assert_eq(sut.get_health(), 90)

Phase 3: 接口实现 (godot-dev)

目标:用最小代码让测试通过

操作

  1. 使用 godot-dev 实现接口
  2. 只写能让测试通过的最小代码

检查点

  • 所有测试通过
  • 符合 GDScript 风格规范

示例

class_name PlayerController extends Node

var _health: int = 100

func get_health() -> int:
    return _health

func take_damage(amount: int) -> void:
    _health = max(0, _health - amount)

Phase 4: 检查验证 (godot-verify)

目标:确保代码质量

操作

  1. 运行 godot-verify 检查:
    • gdlint 代码检查
    • gdformat 代码格式化
    • godot_get_errors 错误解析

检查点

  • lint 通过
  • format 通过
  • 无错误

Phase 5: 运行测试 (godot-test)

目标:最终验证

操作

  1. 运行完整测试套件
  2. 验证覆盖率

检查点

  • 所有测试通过
  • 覆盖率满足要求

循环流程

        ┌──────────────────────────────────────────┐
        │             TDD 循环                      │
        │                                          │
        │  red (写测试) ──→ green (最小实现)        │
        │        ↓                        ↓        │
        │  refactor (重构) ←── verify (检查)       │
        │                                          │
        └──────────────────────────────────────────┘

每个循环后使用 godot-tdd action="next_phase" 进入下一阶段

完整示例

输入

{
  "skill": "godot-tdd",
  "action": "start",
  "feature": "Player受伤系统",
  "description": "实现 Player 受伤后扣除血量并发出信号的功能"
}

预期行为

  1. 设计阶段:用户定义 take_damage() 接口和 health_changed 信号
  2. 测试阶段:编写测试验证伤害计算逻辑
  3. 实现阶段:用户实现 take_damage() 方法
  4. 检查阶段:运行 lint/format 验证代码质量
  5. 验证阶段:运行测试确认功能正确

子 Skill 协调

阶段 调用 Skill 主要工具
设计 godot-design 接口规范检查
测试 godot-test GUT 框架
实现 godot-dev 代码编写
检查 godot-verify gdlint, gdformat
验证 godot-test GUT 运行

进度追踪

当前支持以下进度状态:

  • design - 接口设计阶段
  • test - 测试开发阶段
  • implement - 代码实现阶段
  • verify - 检查验证阶段
  • run_test - 运行测试阶段
  • completed - 功能完成

自动化 TDD 模式

参考 spec-kit 的设计理念,将 TDD 流程转化为 LLM 可自动执行的模式:

spec-kit 概念 自动化实现
spec.md LLM 解析需求 → 生成设计文档
plan.md LLM 生成实现计划
tasks.md LLM 生成 TDD 循环任务

用户参与点 vs LLM 自动化点

阶段 用户 LLM
需求 提供需求描述 -
设计循环 评审设计结果,可能需求澄清 同步更新需求和设计文档
实现循环 不参与 test→implement→verify 全自动化
最终 最终评审 -

完整流程图

┌─────────────────────────────────────────────────────────────────────────┐
│  用户:提供需求描述                                                     │
│       ↓                                                                │
│  ┌──────────────────────────────────────────────────────────────────┐   │
│  │  设计循环 (可能多轮)                                              │   │
│  │  ┌────────────────────────────────────────────────────────────┐  │   │
│  │  │ LLM: analyze + design (符合 godot-design 规范)             │  │   │
│  │  │   - 更新 design.md (需求 + 接口设计)                       │  │   │
│  │  │   - 生成 test_cases.md                                     │  │   │
│  │  │   - 生成伪代码/实现思路                                     │  │   │
│  │  └────────────────────────────────────────────────────────────┘  │   │
│  │       ↓                                                          │   │
│  │  用户:设计评审 + 可能的需求澄清 (循环)                           │   │
│  └──────────────────────────────────────────────────────────────────┘   │
│       ↓                                                                │
│  LLM: 锁定设计文档                                                      │
│       ↓                                                                │
│  ┌──────────────────────────────────────────────────────────────────┐   │
│  │  实现循环 (用户不参与)                                           │   │
│  │  ┌────────────────────────────────────────────────────────────┐  │   │
│  │  │ Phase 2: test                                             │  │   │
│  │  │   - 根据设计创建测试文件                                    │  │   │
│  │  │   - 运行测试 (预期失败, red)                               │  │   │
│  │  └────────────────────────────────────────────────────────────┘  │   │
│  │       ↓                                                          │   │
│  │  ┌────────────────────────────────────────────────────────────┐  │   │
│  │  │ Phase 3: implement                                        │  │   │
│  │  │   - 最小实现让测试通过                                      │  │   │
│  │  │   - 严格遵循设计定义的接口                                  │  │   │
│  │  └────────────────────────────────────────────────────────────┘  │   │
│  │       ↓                                                          │   │
│  │  ┌────────────────────────────────────────────────────────────┐  │   │
│  │  │ Phase 4: verify                                           │  │   │
│  │  │   - gdlint/gdformat 检查                                   │  │   │
│  │  │   - 运行测试 (预期通过)                                    │  │   │
│  │  └────────────────────────────────────────────────────────────┘  │   │
│  └──────────────────────────────────────────────────────────────────┘   │
│       ↓                                                                │
│  用户:最终评审                                                         │
└─────────────────────────────────────────────────────────────────────────┘

设计输出文件规范

参考 spec-kit 输出格式,设计文档输出到项目目录(需求属于设计的一部分):

{project}/
├── specs/                          # 设计文档目录
│   └── {feature}/                  # 按功能划分
│       ├── design.md               # 需求 + 接口设计(合并)
│       ├── test_cases.md           # 测试用例清单
│       └── implementation_plan.md  # 实现计划/伪代码

design.md 模板(需求 + 接口设计)

# {功能名} 设计文档

## 1. 需求描述

### 1.1 功能概述

描述功能的核心目的和业务价值。

### 1.2 功能列表

| 编号 | 功能 | 优先级 | 说明 |
|-----|------|-------|------|
| F1  |      | P0    |      |

### 1.3 用户故事

**作为** [角色]
**我希望** [功能]
**以便** [价值]

### 1.4 输入输出

#### 输入
| 参数 | 类型 | 必填 | 说明 |
|-----|------|-----|------|

#### 输出
| 结果 | 类型 | 说明 |
|-----|------|------|

### 1.5 约束条件

- 性能要求
- 兼容性要求
- 其他约束

### 1.6 验收标准

- [ ] 验收标准1
- [ ] 验收标准2

---

## 2. 接口设计

### 2.1 类定义

#### {ClassName}

```gdscript
class_name {ClassName} extends {BaseClass}

# 导出配置
@export var {prop}: {Type} = {default}

# 私有变量
var _{prop}: {Type}

# 状态查询方法
func get_{property}() -> {Type}:
func is_{condition}() -> bool:

# 动作方法
func {method}({params}) -> {ReturnType}:

# 信号
signal {signal_name}({params})

2.2 接口清单

方法/属性 类型 说明

2.3 状态机设计

| 当前状态 | 操作 | 下一状态 |


3. 版本历史

版本 日期 变更说明
v1.0 初始版本

### test_cases.md 模板

```markdown
# {功能名} 测试用例

## 1. 测试类

`test_{feature}.gd`

## 2. 等价类划分

| 输入类型 | 有效类 | 无效类 |
|---------|-------|-------|
| {param} | 1-100 | <1, >100 |

## 3. 边界值测试

| 用例 | 输入 | 预期 |
|-----|------|------|
| test_{name} | {value} | {result} |

## 4. 状态转换测试

| 当前状态 | 操作 | 下一状态 |

## 5. 版本历史

| 版本 | 日期 | 变更说明 |
|-----|------|---------|
| v1.0 |      | 初始版本 |

接口修改规则

核心原则:实现必须严格遵循设计定义的接口

允许修改接口的流程

发现需要修改接口
┌─────────────────────────────────────────────┐
│  不能直接修改代码!循环到设计阶段            │
│       ↓                                     │
│  1. 在 design.md 中更新接口定义              │
│  2. 更新 test_cases.md (如果需要)           │
│  3. 用户评审设计变更                        │
│  4. 设计确认后重新实现                       │
└─────────────────────────────────────────────┘

禁止行为

  • ❌ 直接在实现代码中修改接口签名
  • ❌ 跳过设计阶段直接添加方法
  • ❌ 忽略设计文档进行编码

注意事项

  1. 每个阶段必须通过检查点才能进入下一阶段
  2. 重构必须确保测试通过
  3. 所有代码修改后必须运行 godot-verify
  4. 测试命名遵循约定test_<类名>_<方法名>_<场景>
Weekly Installs
1
First Seen
6 days ago
Installed on
zencoder1
amp1
cline1
openclaw1
opencode1
cursor1