terrain_forge/
lib.rs

1//! # TerrainForge
2//!
3//! A modular procedural generation engine for terrain, dungeons, and maps.
4//!
5//! ## Quick Start
6//!
7//! ```rust
8//! use terrain_forge::{Grid, Tile, algorithms};
9//!
10//! let mut grid = Grid::new(80, 60);
11//! let algo = algorithms::get("bsp").unwrap();
12//! algo.generate(&mut grid, 12345);
13//!
14//! println!("Generated {} floor tiles", grid.count(|t| t.is_floor()));
15//! ```
16//!
17//! ## Semantic Extraction
18//!
19//! Extract semantic information from any generated map:
20//!
21//! ```rust
22//! use terrain_forge::{algorithms, SemanticExtractor, Grid, Rng};
23//!
24//! // 1. Generate map using any method
25//! let mut grid = Grid::new(80, 60);
26//! algorithms::get("cellular").unwrap().generate(&mut grid, 12345);
27//!
28//! // 2. Extract semantic information
29//! let extractor = SemanticExtractor::for_caves();
30//! let mut rng = Rng::new(12345);
31//! let semantic = extractor.extract(&grid, &mut rng);
32//!
33//! // Works with any grid source - pipelines, external tools, etc.
34//! ```
35//!
36//! ## Algorithms
37//!
38//! 14 generation algorithms available via [`algorithms::get`]:
39//! - `bsp` - Binary Space Partitioning for structured rooms
40//! - `cellular` - Cellular automata for organic caves
41//! - `drunkard` - Random walk for winding corridors
42//! - `maze` - Perfect maze generation
43//! - `rooms` - Simple rectangular rooms
44//! - `voronoi` - Voronoi-based regions
45//! - `dla` - Diffusion-limited aggregation
46//! - `wfc` - Wave Function Collapse
47//! - `percolation` - Connected cluster generation
48//! - `diamond_square` - Heightmap terrain
49//! - `fractal` - Fractal noise terrain
50//! - `agent` - Multi-agent carving
51//! - `glass_seam` - Region connector
52//! - `room_accretion` - Brogue-style organic dungeons
53//!
54//! ## Composition
55//!
56//! Chain algorithms with [`compose::Pipeline`] or layer with [`compose::LayeredGenerator`]:
57//!
58//! ```rust
59//! use terrain_forge::{Grid, Tile, Algorithm, algorithms};
60//! use terrain_forge::compose::Pipeline;
61//!
62//! let mut grid = Grid::new(80, 60);
63//! let pipeline = Pipeline::new()
64//!     .add(algorithms::get("rooms").unwrap())
65//!     .add(algorithms::get("cellular").unwrap());
66//! pipeline.generate(&mut grid, 12345);
67//! ```
68//!
69//! ## Effects
70//!
71//! Post-process with [`effects`]: morphology, connectivity, filters, transforms.
72//!
73//! ## Noise
74//!
75//! [`noise`] module provides Perlin, Simplex, Value, Worley with FBM and modifiers.
76
77mod algorithm;
78mod grid;
79mod rng;
80mod semantic;
81mod semantic_extractor;
82mod semantic_visualization;
83
84#[cfg(test)]
85mod semantic_tests;
86
87pub mod algorithms;
88pub mod compose;
89pub mod constraints;
90pub mod effects;
91pub mod noise;
92
93pub use algorithm::Algorithm;
94pub use grid::{Cell, Grid, Tile};
95pub use rng::Rng;
96pub use semantic::{ConnectivityGraph, Marker, Masks, Region, SemanticConfig, SemanticLayers};
97pub use semantic_extractor::{extract_semantics, extract_semantics_default, SemanticExtractor};
98pub use semantic_visualization::{
99    visualize_connectivity_graph, visualize_masks, visualize_region_ids, visualize_regions,
100    visualize_semantic_layers, VisualizationConfig,
101};
102
103/// Generate a map with semantic layers using the new extraction approach
104///
105/// **DEPRECATED**: This function is provided for backward compatibility.
106/// For new code, use the decoupled `SemanticExtractor` approach:
107///
108/// ```rust
109/// use terrain_forge::{algorithms, SemanticExtractor, Grid, Rng};
110///
111/// // Instead of this deprecated approach:
112/// // let (grid, semantic) = generate_with_semantic_tuple("cellular", 80, 60, 12345);
113///
114/// // Use this:
115/// let mut grid = Grid::new(80, 60);
116/// algorithms::get("cellular").unwrap().generate(&mut grid, 12345);
117/// let semantic = SemanticExtractor::for_caves().extract(&grid, &mut Rng::new(12345));
118/// ```
119#[deprecated(
120    since = "0.3.0",
121    note = "Use decoupled SemanticExtractor for better flexibility"
122)]
123pub fn generate_with_semantic(
124    algorithm_name: &str,
125    width: usize,
126    height: usize,
127    seed: u64,
128) -> (Grid<Tile>, Option<SemanticLayers>) {
129    let mut grid = Grid::new(width, height);
130    let mut rng = Rng::new(seed);
131
132    // Generate tiles using any algorithm
133    if let Some(algo) = algorithms::get(algorithm_name) {
134        algo.generate(&mut grid, seed);
135    }
136
137    // Extract semantic layers using the new standalone system
138    let extractor = match algorithm_name {
139        "cellular" => SemanticExtractor::for_caves(),
140        "bsp" | "rooms" | "room_accretion" => SemanticExtractor::for_rooms(),
141        "maze" => SemanticExtractor::for_mazes(),
142        _ => SemanticExtractor::default(),
143    };
144
145    let semantic = extractor.extract(&grid, &mut rng);
146
147    (grid, Some(semantic))
148}