Files
2nd/10_Wiki/Topics/Game_Design/Procedural-Level-Geometry.md
T
2026-05-10 22:08:15 +09:00

5.6 KiB
Raw Blame History

id, title, category, status, canonical_id, aliases, duplicate_of, source_trust_level, confidence_score, verification_status, tags, raw_sources, last_reinforced, github_commit, tech_stack
id title category status canonical_id aliases duplicate_of source_trust_level confidence_score verification_status tags raw_sources last_reinforced github_commit tech_stack
wiki-2026-0508-procedural-level-geometry Procedural Level Geometry 10_Wiki/Topics verified self
PCG
Procedural Generation
Level PCG
Roguelike Generation
none A 0.9 applied
game-design
level-design
pcg
procedural-generation
2026-05-10 pending
language framework
python roguelike / 3d-engine

Procedural Level Geometry

매 한 줄

"매 grammar + constraint = playable layout". Procedural level geometry 는 매 1980s Rogue 의 BSP 부터 매 2010s Spelunky 의 room template, 매 2020s Minecraft / No Man's Sky / Townscaper 의 WFC, 매 2026 ML-assisted hybrid (Pixar's RayBend, Nvidia GANverse) 까지 매 evolution. 매 핵심 trade-off: 매 controllability ↔ matrix variety.

매 핵심

매 algorithm families

  1. BSP / partition: Rogue, NetHack — 매 simple, 매 grid-only.
  2. Cellular automata: Cave generation — 매 organic shape.
  3. Random walk / drunkard: 매 cave / path.
  4. Template + stitching: Spelunky, Enter the Gungeon — 매 controllable.
  5. Wave Function Collapse (WFC): Townscaper, Bad North — 매 high constraint.
  6. Grammar / L-system: Vegetation, dungeons (Lindenmayer).
  7. ML-assisted: 2026 — diffusion-based heightmap, GAN tile generation.

매 pipeline

Seed → Macro layout (zones) → Meso (rooms / chunks)
     → Micro (geometry, props) → Validation → Polish

매 응용

  1. Roguelike dungeons (Caves of Qud, Brogue, Cogmind).
  2. Open-world terrain (Minecraft, Valheim, NMS).
  3. City generation (Cities Skylines mods, Townscaper).
  4. Mission layouts (Hitman freelancer mode, XCOM).

💻 패턴

BSP dungeon

def bsp_split(rect, depth=0, max_depth=4):
    if depth >= max_depth or rect.too_small():
        return [rect.shrink(margin=1)]   # leaf = room
    axis = "h" if rect.w < rect.h else "v"
    cut = random.uniform(0.4, 0.6)
    a, b = rect.split(axis, cut)
    return bsp_split(a, depth+1, max_depth) + bsp_split(b, depth+1, max_depth)

def connect_rooms(rooms, grid):
    for r1, r2 in zip(rooms, rooms[1:]):
        carve_corridor(grid, r1.center, r2.center)

Cellular automata cave

def cave(w, h, fill=0.45, iters=5):
    g = [[1 if random.random() < fill else 0 for _ in range(w)] for _ in range(h)]
    for _ in range(iters):
        g = [
            [smooth(g, x, y) for x in range(w)]
            for y in range(h)
        ]
    return g

def smooth(g, x, y):
    walls = sum(g[y+dy][x+dx]
                for dy in (-1,0,1) for dx in (-1,0,1)
                if 0 <= x+dx < len(g[0]) and 0 <= y+dy < len(g))
    return 1 if walls >= 5 else 0

Wave Function Collapse (sketch)

def wfc(tiles, w, h, adjacency):
    grid = [[set(tiles) for _ in range(w)] for _ in range(h)]
    while not all_collapsed(grid):
        x, y = lowest_entropy(grid)
        choice = random.choice(list(grid[y][x]))
        grid[y][x] = {choice}
        propagate(grid, x, y, adjacency)
    return grid

Spelunky-style template stitching

ROOM_TEMPLATES = {
    "side": ["....", "..S.", "....", ".###"],
    "drop": [".S..", "....", "###.", "...."],
    "trap": [["X" if random.random()<.1 else "." for _ in range(4)] for _ in range(4)],
}
def build_level(plan):
    """plan: 4×4 grid of (template_kind)."""
    return [
        ROOM_TEMPLATES[kind] for row in plan for kind in row
    ]

Validation — solvability check

def is_solvable(grid, start, goal):
    return bfs_reachable(grid, start, goal)

def regenerate_until_valid(generator, validate, max_tries=100):
    for _ in range(max_tries):
        level = generator()
        if validate(level):
            return level
    raise GenerationFailure()

L-system dungeon grammar

Axiom: ROOM
Rules:
  ROOM     → ROOM CORRIDOR ROOM
  ROOM     → ROOM CORRIDOR JUNCTION
  JUNCTION → ROOM | LOOP_BACK
Iterations: 4
→ post-process: place geometry, add doors

매 결정 기준

상황 Approach
Tight authored feel needed Template stitching (Spelunky)
Organic cave / terrain Cellular automata + erosion
Strict constraint (city, building) WFC
Branching dungeon BSP + grammar
Open world heightmap Perlin / Simplex + erosion + biome mask
Fully ML-driven (2026) Diffusion + WFC fallback

기본값: Template + WFC hybrid + validation regen-loop.

🔗 Graph

🤖 LLM 활용

언제: 매 roguelike / sandbox / open-world 의 generation system, 매 designer 의 매 toolkit, 매 controllability ↔ variety trade-off discussion. 언제 X: 매 highly-authored linear narrative — 매 PCG 의 cost > benefit.

안티패턴

  • No validation: 매 unreachable goal / 매 closed-off key item.
  • Over-randomization: 매 every tile random = 매 chaos, 매 design intent X.
  • No reproducibility: 매 seed 의 expose 의 X — 매 bug repro / 매 speedrun 의 X.

🧪 검증 / 중복

  • Verified (Shaker / Togelius "Procedural Content Generation in Games" 2016; WFC paper Gumin 2016; Spelunky postmortem GDC 2014).
  • 신뢰도 A.

🕓 Changelog

날짜 변경
2026-05-08 Phase 1
2026-05-10 Manual cleanup — algorithm taxonomy, BSP / CA / WFC / template code, validation pattern