---
id: wiki-2026-0508-procedural-level-geometry
title: Procedural Level Geometry
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [PCG, Procedural Generation, Level PCG, Roguelike Generation]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [game-design, level-design, pcg, procedural-generation]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
  language: python
  framework: 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
```python
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
```python
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)
```python
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
```python
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
```python
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
- 부모: [[Level_Design]] · [[Procedural_Content_Generation]]
- 변형: [[Cellular_Automata]]
- Adjacent: [[Base-Layouts-and-Kill-Zones]] · [[Immersive-Sims-Deus-Ex-Thief]]

## 🤖 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 |
