A concise, hierarchical procedural-generation toolkit combining Wave Function Collapse (WFC), adaptive backtracking, and validation to produce multi-level maps (regions → blocks → tiles).
- Overview: #overview
- Quickstart: #quickstart
- Live dashboard: #live-dashboard
- Examples: #examples
- Configuration: #configuration
- Tests: #running-tests
HAMC is a three-layer procedural content generator:
- Global: assigns regions (e.g., forest, desert, city) across a coarse grid.
- Intermediate: subdivides each global cell into blocks (e.g., grove, sand, residential), handling transitions.
- Local: generates tilemaps inside blocks (e.g., grass, water, sand) with connectivity constraints (rivers, roads).
Core ideas: weighted choices, entropy-based cell selection, constraint propagation, and adaptive backtracking.
- Hierarchical WFC-style generation across three levels
- Weighted probabilities and Shannon-entropy selection
- Connectivity and path validation for rivers/roads
- Transition zones and special block types (oasis, buildings)
- Adaptive backtracking with failure tracking
- Renderer for per-level visualization
- Live browser dashboard streaming the generation process (SSE, no extra deps)
- main.py — CLI entry point
- dashboard.py — live dashboard server (SSE)
- dashboard_static/ — dashboard frontend (HTML/CSS/JS)
- hamc/
- config/ — configuration files
- core/ — cell, entropy, backtracking, validators
- generators/ — global, intermediate, local generators
- visualization/ — rendering utilities
- tests/ — unit tests
- run_tests.py — test runner
For a full tree see the original README in the repo.
- Install
pip install -r requirements.txt- Demo (CLI)
python main.py \
--width 4 --height 3 --subgrid 2 --local 4 --output output --debugOutput includes: output/global_map.png, output/intermediate_map.png, output/final_tilemap.png, and JSON data files.
- Demo (Python)
from hamc.generators.global_generator import GlobalGenerator
from hamc.generators.intermediate_generator import IntermediateGenerator
from hamc.generators.local_generator import LocalGenerator
from hamc.visualization.renderer import MapRenderer
Wg, Hg, S, L = 4, 3, 2, 4
renderer = MapRenderer(tile_size=20, padding=1)
G = GlobalGenerator(Wg, Hg)
G.initialize(); G.collapse()
I = IntermediateGenerator(G, subgrid_size=S)
I.collapse()
# Stitch local tilemaps
Lh, Lw = len(I.cells), len(I.cells[0])
tilemap = []
for br in range(Lh):
row_tiles = []
for bc in range(Lw):
t = I.cells[br][bc].collapsed_value
LG = LocalGenerator(t, L)
LG.collapse()
row_tiles.append([[cell.collapsed_value for cell in r] for r in LG.cells])
for r in range(L):
tilemap.append(sum([b[r] for b in row_tiles], []))
renderer.render_final_map(tilemap, global_size=(Hg, Wg), intermediate_size=(Hg*S, Wg*S)).save('output/final_tilemap.png')Watch the WFC process collapse in real time. The dashboard is a tiny stdlib HTTP server that streams generator events through Server-Sent Events:
python dashboard.py --open # serves http://127.0.0.1:8765
# or
make dashboard PORT=9000The browser UI renders three synchronized canvases (global → intermediate → local) and pulses each cell as it collapses. The right-hand log shows collapses, conflicts, and backtracks with timestamps. Adjust grid sizes, step delay and seed from the side panel.
Hook into the same event stream programmatically by registering a callback:
def observer(event):
print(event["type"], event.get("pos"), event.get("value"))
G = GlobalGenerator(4, 3)
G.set_observer(observer, step_delay=0.05)
G.collapse()All constants and profiles live in hamc/config/. The project supports profile-based JSON configs (development, production, testing) and a runtime loader at hamc.config.advanced_config.
python run_tests.pyTests cover entropy, compatibility, path validation, and propagation/backtracking behavior.
- Open issues for bugs or enhancements
- Fork and create a descriptive PR
- Follow existing test patterns; run run_tests.py
See LICENSE in the repository.
Maintained by @murapadev. Questions or ideas? Open an issue or reach out via GitHub.