Something went wrong. Try again.
HEXWORK - A Lantern in the Deep: 3D ASCII terminal roguelike RPG in Rust.
Entirely designed and built by Muse Spark 1.3 to evaluate if I like the model.
Something went wrong. Try again.
4.7 kB · 159 lines
Rust
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160//! hexwork-worldgen: seeded layouts (docs/04 §4.2, docs/03 §3.8).//! Hand-designed anchor rooms + systemic fill. Every floor guarantees//! 3+ vertical connectors, an airflow network, and a water path.
pub mod deep;pub mod runtime;
pub use runtime::{ is_supported_standing, route_exists, route_exists_with_policy, validate_deep_links, ActorRole, ActorSpawnPlan, AirflowEdge, AirflowPlan, Bounds, Cell, ConnectorPlan, FloorPlan, InteractionAnchor, InteractionKind, ItemSpawnPlan, Job, MechanicHook, MovementPolicy, NamedAnchor, PlanDestination, PlanValidationError, PressureZone, RoadPlan, SpawnZone, TransitionDirection, VoxelWrite, WorldPlan,};
use hexwork_core::connector::{Connector, ConnectorKind};use hexwork_core::rng::{domains, Rng};
/// Which stratum a floor belongs to: Shallows 1-3, Works 4-8, Deep 9-12.#[derive(Clone, Copy, Debug, PartialEq, Eq)]pub enum Stratum { Shallows, Works, Deep,}
/// A generated floor: anchor rooms plus connectors. Voxel fill arrives in Phase 2+.#[derive(Clone, Debug)]pub struct Floor { pub depth: u8, pub stratum: Stratum, pub seed: u64, pub anchors: Vec<String>, pub connectors: Vec<Connector>,}
pub fn stratum_for(depth: u8) -> Stratum { match depth { 1..=3 => Stratum::Shallows, 4..=8 => Stratum::Works, _ => Stratum::Deep, }}
/// Generate a floor deterministically from run seed + depth.pub fn generate_floor(master_seed: u64, depth: u8) -> Floor { let mut rng = Rng::from_seed(master_seed ^ (depth as u64).wrapping_mul(0x9E3779B97F4A7C15)); let mut rng = rng.fork(domains::WORLDGEN); let stratum = stratum_for(depth); let anchors = anchor_set(stratum, &mut rng); // Guarantee: 3+ vertical connectors per floor (docs/03 §3.8). let kinds = [ ConnectorKind::Stairwell, ConnectorKind::Shaft, ConnectorKind::Vent, ]; let mut connectors = Vec::new(); for (i, kind) in kinds.iter().enumerate() { let z_top = -(depth as f32) * 10.0; connectors.push(Connector { id: (depth as u64) * 100 + i as u64, kind: *kind, from: [i as f32 * 8.0, 0.0, z_top - 10.0], to: [i as f32 * 8.0, 0.0, z_top], length: 12.0, anchor_quality: 60 + rng.below(41) as u8, load_kg: 0.0, blocked: false, }); } Floor { depth, stratum, seed: master_seed ^ (depth as u64), anchors, connectors, }}
/// Generate an apply-ready Milthollow plan without mutating runtime state.#[must_use]pub fn milthollow(seed: u64) -> WorldPlan { runtime::build_milthollow(seed)}
/// Generate one apply-ready Deep floor for a depth in `1..=12`.////// # Panics/// Panics when `depth` is outside the twelve playable floors.#[must_use]pub fn playable_floor(master_seed: u64, depth: u8) -> FloorPlan { runtime::build_playable_floor(master_seed, depth)}
/// Generate the complete twelve-floor Deep in ascending depth order.#[must_use]pub fn playable_deep(master_seed: u64) -> Vec<FloorPlan> { let floors: Vec<_> = (1..=12) .map(|depth| playable_floor(master_seed, depth)) .collect(); assert!( validate_deep_links(&milthollow(master_seed), &floors).is_ok(), "generated Deep transition graph must validate" ); floors}
fn anchor_set(stratum: Stratum, rng: &mut Rng) -> Vec<String> { let pool: &[&str] = match stratum { Stratum::Shallows => &[ "root-cellar relay", "sewer chapel", "collapsed stair", "rat warren", "tinker cache", ], Stratum::Works => &[ "elevator hall", "audit vault", "flooded shaft", "server shrine", "counterweight gallery", ], Stratum::Deep => &[ "dream chapel", "sideways fall", "saint throne", "choir loft", "idle gate", ], }; let n = 3 + rng.below(3) as usize; let mut out = Vec::new(); for _ in 0..n { out.push(pool[rng.below(pool.len() as u64) as usize].to_string()); } out}
#[cfg(test)]mod tests { use super::*;
#[test] fn three_connectors_minimum() { for depth in 1..=12 { let f = generate_floor(99, depth); assert!(f.connectors.len() >= 3, "floor {depth} needs 3+ connectors"); } }
#[test] fn deterministic_floors() { assert_eq!( format!("{:?}", generate_floor(5, 2).anchors), format!("{:?}", generate_floor(5, 2).anchors) ); }}