mcpField
P
procedural-gen

procedural-gen

github.com/gamedev-skills开发5.4k7.9k 次安装1 天前更新
代码仓库

关于 procedural-gen

procedural-gen 是面向游戏开发的程序化生成技能,用紧凑规则和种子生成关卡、地形与战利品。重点是确定性生成、验证连通性,并将生成数据与绘制分开。

主要功能

  1. 01基于种子的确定性随机生成
  2. 02噪声地形与高度图生成
  3. 03房间、走廊和洞穴布局
  4. 04按权重选择战利品
  5. 05生成后验证连通性

适用场景

  1. 01生成可复现的地牢地图
  2. 02构建地形和生物群系
  3. 03按稀有度生成物品掉落

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/gamedev-skills/awesome-gamedev-agent-skills --skill procedural-gen

安装后在 Claude Code 中输入/procedural-gen确认已加载。

附带文件references/dungeon-generation.mdreferences/noise.md

详细介绍

程序化生成

通过简洁的规则和种子生成关卡、地形与战利品。优秀程序化生成的核心在于确定性:同一个种子会生成相同的世界,因此错误可以复现,玩家也能分享种子。这项技能负责核心算法——噪声、种子化 RNG、地牢布局、加权表;roguelike 和 survival-crafting 等类型会使用这些算法。

适用场景

  • 需要生成地图、地牢、地形高度图、物品掉落或任何不想手动制作的内容时。
  • 结果必须可通过种子复现时(例如调试、每日挑战、可分享的世界)。
  • 需要从加权随机结果中进行选择时(例如战利品稀有度、生成表)。

**不适用场景:**如果要使用引擎的图块 API 绘制生成结果,请使用 godot-tilemap 或 unity-tilemap-2d。如果要让 AI 在生成的地图中寻路,请使用 game-ai。如果要精心设计节奏的手工关卡,请使用 level-design——程序化生成与手工设计相辅相成,并不能互相替代。

核心工作流

  1. 管理自己的随机数。 创建一个种子化 RNG 实例,并传递到各处。生成代码中绝不要调用全局或静态随机数函数——否则结果将无法复现,并且会受调用顺序影响。
  2. 根据内容选择技术。 连续地形/高度图 → 噪声。离散房间/走廊 → 空间划分或基于 Agent 的挖掘。具有不同稀有度的结果 → 加权表。
  3. 先生成到普通数据网格/数组中,与渲染分离。生成过程填充 int[][] 或字典;再由单独的流程绘制。
  4. 将结果交给玩家前先验证。 每个房间都可到达吗?出生点安全吗?有路通往出口吗?拒绝或修复不合格的布局;不要把损坏的地图交给玩家。
  5. 固定种子进行调优,这样每次参数变更的效果都能单独体现;然后遍历多个种子检查分布,而不只是检查一张幸运生成的地图。

模式

1. 种子化、确定性的 RNG(基础)
import random
rng = random.Random(seed)        # a dedicated instance — NOT the global random.*
room_count = rng.randint(5, 12)  # same seed -> same sequence, every run
# RIGHT: thread `rng` through every function that makes a choice.
# WRONG: calling random.randint(...) (global state) — order-dependent, unseedable.

引擎中的对应写法:Godot var rng = RandomNumberGenerator.new(); rng.seed = s;Unity var rng = new System.Random(seed)(或 UnityEngine.Random.InitState)。将种子存入存档文件,以便重新生成世界。

2. 用于高度图的分形(fBm)噪声
# Sum several octaves: each higher octave has higher frequency, lower amplitude.
def fbm(noise, x, y, octaves=5, lacunarity=2.0, gain=0.5):
    total, amp, freq, norm = 0.0, 1.0, 1.0, 0.0
    for _ in range(octaves):
        total += amp * noise(x * freq, y * freq)   # noise() returns ~0..1
        norm  += amp                                # track total amplitude
        amp   *= gain                               # each octave contributes less
        freq  *= lacunarity                         # ...at a higher frequency
    return total / norm                             # normalize back into 0..1

# Redistribute to carve flat valleys / sharpen peaks: higher exp -> more lowland.
elevation = pow(fbm(noise, nx, ny), 2.2)

使用现成的噪声库(FastNoiseLite、opensimplex、Unity.Mathematics.noise 或 Mathf.PerlinNoise)——不要自行实现梯度噪声。使用不同的种子来生成海拔和湿度,这样根据两个场查询生物群系时,不会产生完全相关的结果。完整的生物群系查询和岛屿塑形内容见 references/noise.md。

3. 加权战利品表(正确选择稀有度)
# Roll proportional to weight: common drops far more often than legendary.
def weighted_pick(rng, table):           # table: list of (item, weight)
    total = sum(w for _, w in table)
    roll = rng.uniform(0, total)          # a point on the cumulative line
    upto = 0.0
    for item, w in table:
        upto += w
        if roll < upto:                   # first bucket the roll falls into
            return item
    return table[-1][0]                   # float-safety fallback

loot = weighted_pick(rng, [("common", 70), ("rare", 25), ("legendary", 5)])

权重不必加总为 100——它们只表示相对权重。为避免连续出现不理想结果,可使用“保底”/抽袋系统(分布相关说明见 references/dungeon-generation.md)。

4. 房间与走廊地牢(示意)
# 1. Place non-overlapping rooms; 2. connect them; 3. carve into the grid.
rooms = []
for _ in range(attempts):
    r = Rect(rng.randint(1, W-w-1), rng.randint(1, H-h-1), w, h)
    if not any(r.intersects(o.expand(1)) for o in rooms):  # keep a 1-tile gap
        rooms.append(r)
for a, b in zip(rooms, rooms[1:]):       # connect each room to the next
    carve_l_corridor(grid, a.center, b.center, rng)   # horizontal then vertical

完整生成器(BSP 划分、L 形走廊、可达性检查和随机游走洞穴)见 references/dungeon-generation.md。

常见问题

  • 在生成过程中使用全局 RNG 会导致世界无法复现,并且一旦调用顺序发生变化就会出错。始终传入一个已设定种子的实例。
  • 噪声场相关:使用相同的种子/偏移量采样海拔和湿度,会导致生物群系呈带状排列。为每个场设置不同的偏移量或重新设定种子。
  • 倍频程伪影:添加倍频程却不重新归一化,会使数值超出 0..1;应除以振幅总和(并留意库的输出范围——有些返回 -1..1,有些返回 0..1)。
  • 未检查连通性:房间或洞穴可能会彼此隔离。游戏开始前,从出生点进行泛洪填充,并丢弃或重新连接无法到达的区域。
  • 无界放置循环:“不断尝试,直到容纳 N 个房间”可能会在小网格上无限循环。限制尝试次数,并接受房间数量较少的结果。
  • 只进行一次全局设种,然后依赖帧时间:任何泄漏到生成过程中的非确定性输入(时间、物理、哈希随机化)都会破坏可复现性。

参考资料

  • references/noise.md — 倍频程/疏密度/增益、重新分布、岛屿塑形、双轴生物群系查找、蓝噪声对象散布。
  • references/dungeon-generation.md — BSP、房间与走廊、随机游走洞穴、元胞自动机平滑、连通性验证、分布/保底表。

相关技能

  • godot-tilemap、unity-tilemap-2d — 将生成的网格绘制到引擎中。
  • game-ai — 在生成的图上寻路。
  • level-design — procgen 所补充的节奏控制和手工设计结构。
  • roguelike、survival-crafting — 运用此技能的游戏类型。

评论

支持 Markdown