Axıs
技能目录

21 · 程序化生成系统设计

21 · 程序化生成系统设计

独立游戏买不起内容量,PCG 是唯一负担得起的规模化手段。 但 PCG 的成本曲线是前重后轻:前期投入大,后期边际成本近零——选它之前先确认你付得起前期。 渲染/管线实现见 game-tech-art/domains/05-procedural-generation.md;本文件管设计侧:生成什么、怎么控制、怎么验证。

1. 先决策:该不该用 PCG

维度 手工内容 程序生成
成本曲线 线性(每关都是钱) 前重后轻
质量上限 高(可精雕) 中(但可通过约束逼近)
多样性 低(设计师产能上限) 高
可读性 高 风险点
节奏控制 精确 需额外机制
适合 叙事、解谜、银河城 Roguelike、生存、沙盒、自动生成关卡

决策三问:

  1. 我需要的内容量是否远超团队手工产能?(例如 500 个关卡)
  2. 我的核心循环是否依赖每次不同?(重复感是致命的)
  3. 我能否接受"生成的每一局不是最好的那一局"?

三个"是" → 用 PCG。任一"否" → 手工内容质量更高。

混合策略(最实用):手工做骨架(关键关卡、Boss、教学),PCG 做填充与变奏。 例:手工设计 5 个房间模板 → PCG 组合与参数化 → 手工挑选最优的 20 个变体入库。

2. 生成的三个层次

层 生成什么 例子 难度
L1 布局生成 空间、地形、物件位置 地牢房间布局、平台跳跃段落 中
L2 内容生成 数值、词缀、掉落、敌人组合 词缀装备、随机词条、敌人波次 低(最推荐)
L3 规则生成 规则本身、系统参数 每局不同规则的修饰器、Balatro 的随机小丑池 高(深度最高)

独立游戏建议:L2 是性价比最高的层——成本低、玩家感知强、易于平衡。 L1 需要空间设计能力,容易做出"能走但不好玩"的地图。 L3 是 Balatro / StS 式深度的来源,但需要极强的约束设计。

3. 生成语法(Grammar):从约束到输出

核心思路:不要写"生成器",要写"语法"。 语法定义合法的组合规则,生成器只是语法的执行器。

[语法]
S → 章节
章节 → 引入段 + 变奏段×2~3 + 考试段
引入段 → 1 个新机制 + 安全练习场
变奏段 → 已教机制的组合 + 递增强度
考试段 → 综合考验 + 奖励

[约束]
- 引入段必须出现在任何变奏段之前
- 新机制在考试段前至少出现 2 次
- 连续两个变奏段不能使用同一机制组
- 章节末必须有一次释放段

语法的三个好处:

  1. 可控:约束保证生成结果符合设计意图
  2. 可验证:可以检查生成结果是否满足约束
  3. 可迭代:改语法而非改生成器代码

语法设计步骤:

  1. 手写 3–5 个"理想样例",找它们的共同结构
  2. 把这个结构抽象成产生式规则
  3. 列出"绝对不能出现"的情况 → 约束
  4. 写生成器
  5. 跑 1000 次,人工抽查 20 个,统计约束违反率

4. 可控随机的四种技术

技术 做法 用途
种子(Seed) 一切随机源自一个种子 可复现、可分享、可 debug、社区可玩"每日种子"
权重曲线 不平均随机,按权重抽取(前期小怪多,后期精英多) 控制难度曲线与节奏
约束求解 生成后检查约束,不满足则重新生成或修补 保证可解性与设计意图
后处理修正 生成后做一次"设计师之手"的修正(补关键路径、加引导) 提升可读性与体验

必须用种子的三个理由:

  1. Bug 复现:玩家报告"第 3 关过不去"时,有种子就能复现
  2. 平衡测试:固定种子跑 1000 次,对比不同版本的数值
  3. 社区长尾:每日种子/种子分享 = 零成本的社区内容

约束求解的成本控制:拒绝采样(重新生成)最便宜,但约束多时成功率骤降。 经验阈值:单次生成成功率 < 20% 时,改用修补式生成(生成后局部修正)而非重试。

5. 生成质量验证(五道检查)

生成的每一份内容都必须过这五关,否则它是"能玩但不好玩"的。

# 检查 判据 失败后果
1 可解性 存在至少一条通关路径 卡死(最严重的 bug)
2 可读性 关键路径可辨认,无死胡同无回报 迷路、挫败
3 节奏 强度曲线符合目标模板(见 principles/02 §5) 忽难忽易
4 多样性 连续 N 局的相似度低于阈值 重复感
5 公平性 无"必死局"、无"资源荒漠" 不可归因的失败

自动化验证:

  • 可解性 → 用寻路/求解器自动验证(必须自动化,人工抽查不够)
  • 节奏 → 计算生成结果的强度序列,与目标模板做距离比较
  • 多样性 → 计算特征向量(房间数、敌人构成、资源分布),看分布是否过窄
  • 公平性 → 模拟机器人跑通,记录死亡率与死因

多样性指标参考:

指标 健康值
连续 10 局的特征向量平均距离 > 阈值(因游戏而异,先测基线)
出现率最高的模板占比 < 30%
从未出现的合法组合 接近 0

6. 用生成器产生难度曲线

PCG 最大的诱惑是"完全随机",但玩家需要可学习的节奏。

手法 做法
难度作为生成参数 把"目标强度"作为输入,生成器按强度选元素
阶段化语法 前 1/3 只生成已教元素,中 1/3 生成组合,后 1/3 生成高压
保底机制 连续 N 次生成"太简单"→ 强制提升强度;反之亦然
手工锚点 关键节点(第 1 关、Boss 前、结局前)用手工内容锚定

反模式:纯随机难度 → 玩家无法建立模型 → "这游戏靠运气"。

7. 独立游戏实操

项 建议
工具 优先用引擎自带(Unity Tilemap + 自定义规则、Godot 的生成节点);不要自研通用生成框架
可视化调试 必须做:能一键显示生成过程、约束检查结果、种子、重生成
批量预览 做一个"生成 100 个并平铺预览"的工具,人工挑选质量基准
版本快照 记录"哪个种子 + 哪个生成器版本 = 哪个结果",否则无法复现
生成时间预算 单次生成 < 100ms(否则玩家等);大世界可做异步/分块
内容入库 生成结果好的,人工标记入库,作为后续生成的模板

成本警示:PCG 的调试成本常被低估。一个"看起来对"的生成器,可能需要 2–3 倍于预期的时间来调好可读性与节奏。

8. 与手工内容的边界

内容 手工 生成
教学关 ✅ 必须手工 ❌
Boss ✅ 手工 ❌
关键剧情节点 ✅ 手工 ❌
常规关卡布局 ⚠️ 骨架 ✅ 填充与变奏
敌人组合/波次 ⚠️ 规则 ✅ 执行
数值/词缀/掉落 ⚠️ 曲线 ✅ 抽取
秘密与彩蛋 ✅ 手工 ⚠️ 可用生成器"藏"

铁律:第一印象必须手工。 前 10 分钟、第一个 Boss、第一次转折——这些决定玩家是否留下,不能交给生成器。

9. 反模式

症状 修法
生成的关卡"能走但不好玩" 补后处理修正 + 可读性检查
玩家报告卡死无法复现 必须用种子
连续几局感觉一样 补多样性指标与约束
难度忽难忽易 把难度作为生成参数 + 保底机制
生成成功率 < 20% 改修补式生成,别硬重试
自研通用生成框架 用引擎自带,把时间花在语法上
完全没有手工锚点 教学关/Boss/前 10 分钟必须手工
单次生成 > 100ms 分块/异步/预生成
无批量预览工具 做"生成 100 个平铺"工具
只做 L1 布局生成 L2 内容生成性价比更高
生成器版本与结果无关联 记录"种子 + 生成器版本"

10. 交付物

  1. 生成语法文档:产生式规则 + 约束清单
  2. 五道检查的自动化验证脚本(可解性必须自动)
  3. 种子系统规格(含每日种子/分享机制)
  4. 批量预览报告:100 个生成样本 + 质量分布
  5. 手工/生成边界表

11. 参考

  • game-tech-art/domains/05-procedural-generation.md(实现侧)
  • Kate Compton, GDC《Practical Procedural Generation for Everyone》——生成空间与可控性
  • 案例:Noita(规则生成)、Balatro(小丑池 L3)、StS(地图生成 L1)、Rimworld(AI 叙事者 + 事件生成)