AI Game Level Generator
根据自然语言描述,生成结构化的游戏关卡配置文件。 支持多种关卡范式:网格地图、波次敌人、道具分布、区域触发器。 输出格式为引擎无关的 JSON 或 YAML,可直接被任意游戏引擎读取。
⚠️ Hard Rules
- 生成前必须读取项目已有关卡 — 禁止凭空生成格式。必须先读取项目中已有的关卡文件推断 Schema 结构,保持格式一致。如果项目中没有已有关卡,使用默认 Schema 并告知用户
- 数值必须通过约束校验 — 敌人数量、资源总量、难度曲线必须在合理范围内。禁止生成不可通关的关卡(如出口被堵死、敌人血量无穷大)
- 禁止覆盖已有关卡 — 生成新关卡时必须检查目标路径是否已有同名文件,冲突时询问用户选择覆盖或重命名
- 坐标必须在边界内 — 所有实体的坐标不得超出地图尺寸,spawn 点不得与障碍物重叠
- 先预览后写入 — 生成结果必须先以结构化摘要展示给用户确认,用户同意后才写入文件。禁止静默写入
- 引擎无关 — 输出格式为通用 JSON/YAML,不得包含任何特定引擎的私有格式或 API 引用
触发条件
当用户说以下内容时触发本 Skill:
- "生成一个关卡" / "设计一个新地图" / "做一个地下城"
- "创建第 N 关的配置" / "生成 boss 关" / "设计最终关"
- "编排敌人波次" / "设计无尽模式的怪物刷新"
- "能不能自动生成关卡配置"
- "generate a level" / "create wave config" / "design dungeon layout"
不触发条件
以下情况应使用其他 Skill:
- 用户想手动调整已有关卡的某个数值 → 直接编辑配置文件
- 用户想生成关卡所需的美术素材(贴图、模型) → 使用
ai-game-asset-pipeline - 用户想验证关卡是否可以通关 → 使用
ai-game-playtester - 用户想设计关卡的叙事剧情(不是数据配置) → 不属于本 Skill
输入参数
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
description |
string | ✓ | - | 关卡的自然语言描述 |
level_type |
string | grid |
关卡类型:grid(网格地图)/ wave(波次刷怪)/ platform(平台跳跃) |
|
difficulty |
string | normal |
难度:easy / normal / hard / nightmare |
|
output_format |
string | json |
输出格式:json / yaml |
|
output_path |
string | levels/ |
输出目录 |
执行流程
步骤 0:前置检查 — 读取项目关卡结构
在生成任何内容之前,必须先理解项目的关卡数据格式。
- 扫描项目中已有的关卡文件:
查找 levels/*.json, levels/*.yaml, data/levels/*, config/levels/*, assets/data/*.json - 若找到已有关卡文件 → 读取 1-2 个文件,推断 Schema 结构
- 若未找到 → 告知用户将使用默认 Schema,使用以下默认结构
默认 Schema(无已有关卡时使用):
{
"level_id": "string — 唯一标识",
"name": "string — 显示名称",
"difficulty": "easy | normal | hard | nightmare",
"map": {
"width": "number — 地图列数",
"height": "number — 地图行数",
"tiles": "number[][] — 二维数组,0=空地 1=墙壁 2=出生点 3=出口",
"objects": [
{ "type": "string", "x": "number", "y": "number", "properties": {} }
]
},
"waves": [
{
"wave_id": "number",
"delay_seconds": "number — 本波次等待秒数",
"enemies": [
{ "type": "string", "count": "number", "spawn_area": "string" }
]
}
],
"rewards": {
"coins": "number",
"exp": "number",
"items": ["string — 道具 ID"]
}
}
步骤 1:意图解析
从用户的自然语言描述中提取以下关键要素:
| 要素 | 用户说 | 解析结果 | 未提及时默认值 |
|---|---|---|---|
| 地图尺寸 | "小地图" / "大地图" | 8x8 / 32x32 | 16x16 |
| 敌人种类 | "有骑士和射手" | ["knight", "archer"] |
使用项目已有敌人类型,若无则用 ["enemy_basic"] |
| 难度分布 | "前松后紧" | 渐进式递增 | 线性递增 |
| 主题 | "冰雪场景" | 用于命名和描述 | 无主题约束 |
| 特殊机关 | "有陷阱和宝箱" | ["trap", "chest"] |
无 |
| 波次数 | "5波怪" | wave_count: 5 |
difficulty 对应值(easy:3, normal:5, hard:8, nightmare:12) |
步骤 2:生成关卡配置
根据解析结果和 Schema 生成关卡配置。
难度系数参考:
| 难度 | 每波敌人数系数 | 敌人血量系数 | 奖励系数 | 默认波次数 |
|---|---|---|---|---|
| easy | 0.6x | 0.7x | 1.2x | 3 |
| normal | 1.0x | 1.0x | 1.0x | 5 |
| hard | 1.5x | 1.4x | 0.8x | 8 |
| nightmare | 2.0x | 2.0x | 0.6x | 12 |
波次编排规则:
- 第 1 波:仅基础兵种,数量少,作为热身
- 中间波次:逐步引入新兵种类型,每隔 2 波引入 1 种
- 倒数第 2 波:数量达到峰值
- 最后一波:Boss 或精英首领 + 少量护卫兵
- 每波间隔:easy 8s / normal 5s / hard 3s / nightmare 2s
地图生成规则(grid 类型):
- 边界必须是墙壁(tiles[0][]、tiles[height-1][]、tiles[][0]、tiles[][width-1] = 1)
- 出生点 (type=2) 和出口 (type=3) 之间必须存在可通行路径
- 障碍物密度:easy 15% / normal 25% / hard 35% / nightmare 45%
- 宝箱/道具放置在死角或支路,不放在必经之路上
步骤 3:约束校验
生成后必须执行以下校验:
| 校验项 | 规则 | 失败处理 |
|---|---|---|
| 坐标边界 | 所有 object 的 x/y 在 [0, width) 和 [0, height) 范围内 | 自动夹到最近合法位置 |
| 可达性 | 出生点到出口之间存在可通行路径(BFS/DFS 验证) | 重新生成地图布局(最多重试 3 次) |
| 敌人总量 | 单波不超过 50 个,所有波次总量不超过 500 个 | 超过时自动拆分为更多波次 |
| 奖励平衡 | coins 在 [difficulty_base * 0.5, difficulty_base * 2.0] 范围内 | 按系数自动调整 |
| 出生点与障碍 | 出生点、出口位置必须是空地 (tile=0) | 清除冲突位置的障碍物 |
| 文件名冲突 | {output_path}/{level_id}.{format} 不存在同名文件 |
询问用户是否覆盖 |
步骤 4:迭代优化(校验不通过时)
当步骤 3 的校验未全部通过时,进入迭代优化循环(最多 3 轮):
- 记录失败日志:
🔄 迭代日志 (第 N/3 轮)
━━━━━━━━━━━━━━━━━━━━
❌ 失败项: 可达性校验
期望: 出生点 (2,2) 到出口 (21,21) 存在可通行路径
实际: 路径被 (12,11) 处障碍物阻断
原因: 障碍物密度 35% 导致中部区域全封闭
调整: 降低中部区域障碍物密度至 20%,保留边缘密度
- 分析根因 — 判断失败类型:
- 坐标越界 → 自动夹到合法位置,重新校验
- 地图不可达 → 降低障碍物密度或清除关键路径障碍,重新生成
- 敌人数量超限 → 拆分波次或降低系数,重新校验
- 奖励失衡 → 按难度系数自动调整
- 执行修正 — 调整参数后重新执行步骤 2 → 步骤 3
- 对比改善:
修正结果: ✅ 可达性校验通过(障碍物密度 35% → 28%)
- 终止条件 — 3 轮后仍有失败项 → 输出完整迭代日志,报告用户人工介入
步骤 5:展示预览
将生成结果以结构化摘要展示给用户:
📋 关卡预览:冰霜深渊 (level_frost_abyss_01)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
难度: Hard | 地图: 24x24 | 波次: 8 | 格式: JSON
🗺️ 地图概览:
- 出生点: (2, 2)
- 出口: (21, 21)
- 障碍物密度: 35%
- 宝箱: 3 个
- 陷阱: 5 个
- 可达性校验: ✅ 通过
👾 波次编排:
Wave 1: 冰霜剑士 x4 (热身) [间隔 3s]
Wave 2: 冰霜剑士 x6 + 寒冰弓箭手 x3
Wave 3: 冰霜射手 x4 + 寒冰弓箭手 x5
Wave 4: 精英冰霜骑士 x2 + 冰霜剑士 x8
...
Wave 8: 🧊 冰霜领主 x1 + 冰霜骑士 x4
🎁 通关奖励: 金币 800 | 经验 2000 | 寒冰之刃
确认写入? [Y/n]
用户确认后才执行步骤 6。
步骤 6:写入文件
- 若
output_path目录不存在 → 自动创建 - 将关卡配置写入
{output_path}/{level_id}.{format} - 写入后输出确认:
✅ 关卡已保存: levels/level_frost_abyss_01.json (3.1 KB)
完成标志
关卡文件写入成功且所有校验通过后,输出:
<promise>DONE</promise>
错误处理
| 场景 | 处理方式 |
|---|---|
| 项目中无法推断关卡 Schema | 使用默认 Schema,告知用户 |
| 生成的地图不可通行 | 最多重试 3 次,仍失败则降低障碍物密度至 10% 重试 |
| 用户描述过于模糊(如只说"做个关卡") | 列出 2-3 个具体方案供选择,不要自行假设 |
| 输出目录不存在 | 自动创建目录 |
| 文件写入失败(权限问题) | 报告具体错误,建议检查目录权限 |
与其他 Skill 的协作
用户描述关卡需求
↓
ai-game-level-generator (本 Skill)
├─ 读取项目已有关卡推断格式
├─ 生成关卡配置 JSON/YAML
├─ 约束校验 + 可达性验证
└─ 输出 level_id 和文件路径
↓
ai-game-asset-pipeline (可选)
├─ 根据关卡主题生成美术素材
└─ 导入项目资源目录
↓
ai-game-playtester (可选)
├─ 自动运行关卡
└─ 验证可通关性和体验评分