Skip to main content

roxlap_cavegen/
lib.rs

1//! Procedural cave generation for the roxlap voxel engine.
2//!
3//! Builds voxlap-format `Vxl` worlds from a Worley-noise + Perlin-
4//! overlay classification scheme. The crate ships two presets
5//! ([`BlueCaveGenerator`], [`MagCaveGenerator`]) tuned to match
6//! Ken Silverman + Tom Dobrowolski's 2003 "Justfly" reference
7//! screenshots (`caveblue2m.jpg`, `cavemag3m.jpg`).
8//!
9//! # Pipeline
10//!
11//! 1. [`Generator::generate`] consumes [`CaveParams`] (seed +
12//!    shape knobs) and produces a [`Vxl`].
13//! 2. Internally, generators sample a dense `(VSID × VSID × MAXZDIM)`
14//!    voxel mask + colour grid via Worley distance classification +
15//!    Perlin overlay.
16//! 3. [`pack_dense_grid_to_vxl`] folds the dense grid into voxlap's
17//!    slab-RLE column format — much faster than feeding voxels
18//!    through the [`set_spans`] edit pipeline for whole-world
19//!    creation.
20//!
21//! [`set_spans`]: ../roxlap_formats/edit/fn.set_spans.html
22
23pub use roxlap_formats::vxl::Vxl;
24
25mod pack;
26mod perlin;
27mod presets;
28mod rng;
29mod worley;
30
31pub use pack::{pack_dense_grid_to_vxl, MAXZDIM};
32pub use perlin::PerlinNoise3D;
33pub use presets::{BlueCaveGenerator, MagCaveGenerator};
34pub use worley::{
35    classify_voxel, classify_voxel_with_perlin, place_seeds, worley_classify_grid, Seed,
36};
37
38/// Parameters for the procedural cave generators.
39///
40/// All fields are public so callers can override per-preset defaults.
41/// Generators are expected to fall back to their preset-specific
42/// defaults when the user constructs a `CaveParams` via
43/// [`CaveParams::default`] — that returns the "blue cave" baseline
44/// from `caveblue2m.jpg`. Other presets (e.g.,
45/// [`MagCaveGenerator`]) supply their own defaults via factory
46/// constructors.
47#[derive(Debug, Clone, Copy, PartialEq)]
48pub struct CaveParams {
49    /// RNG seed. Same seed + same params + same code → byte-stable
50    /// output. Promotes determinism across runs and platforms.
51    pub seed: u64,
52    /// Number of Worley seed points placed in the volume. Controls
53    /// the cave's chamber-vs-corridor texture.
54    pub seed_count: usize,
55    /// Fraction of seeds tagged "air" (the rest are "solid").
56    /// Higher values produce more open caves.
57    pub air_ratio: f32,
58    /// Per-seed distance scaling factor — voxlap `CaveTex`'s "shape"
59    /// parameter. 1.0 produces isotropic Worley cells; > 1.0
60    /// elongates them along an arbitrary axis.
61    pub anisotropy: f32,
62    /// Number of Perlin-noise octaves overlaid on the air/solid
63    /// boundary to break up Worley's clean facets.
64    pub perlin_octaves: u32,
65    /// Magnitude of the Perlin overlay (added to `d_a` in the
66    /// classification step). Larger values give more organic
67    /// surfaces; 0 disables overlay.
68    pub perlin_amplitude: f32,
69}
70
71impl Default for CaveParams {
72    /// "Blue cave" baseline matching `caveblue2m.jpg`.
73    fn default() -> Self {
74        Self {
75            seed: 7,
76            seed_count: 128,
77            air_ratio: 0.5,
78            anisotropy: 1.0,
79            perlin_octaves: 3,
80            perlin_amplitude: 0.15,
81        }
82    }
83}
84
85/// Procedural world generator. Implementors produce a [`Vxl`] from
86/// [`CaveParams`] (or their own typed parameter struct).
87///
88/// `generate` is expected to be deterministic in its parameters: the
89/// same `params + vsid` MUST produce a byte-stable [`Vxl`] across
90/// runs (within the same toolchain — like the rasterizer's tests,
91/// cross-CPU FP determinism is best-effort).
92pub trait Generator {
93    /// Parameter type. Most generators alias this to [`CaveParams`].
94    type Params;
95
96    /// Build a `vsid × vsid × MAXZDIM` voxel world per `params`.
97    /// `vsid` MUST be a power of two and `>= 4` (smaller worlds
98    /// don't have room for the central air carve).
99    fn generate(&self, params: &Self::Params, vsid: u32) -> Vxl;
100}
101
102// `BlueCaveGenerator` (CD.6) and `MagCaveGenerator` (CD.7) live in
103// `presets.rs`; re-exported above.