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.
2.3 kB · 85 lines
Rust
at main
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586//! Cause-link recorder: every death, injury, and major event stores the//! rule chain that produced it (docs/04 §4.2 phase 12, docs/03 §3.9).//! Powers epitaphs, death replays, and tutorial subtitles.
/// One link in a causal chain: `rule` names the law (e.g. "rooms breathe"),/// `detail` is the NetHack-voice line shown to the player.#[derive(Clone, Debug, PartialEq, Eq)]pub struct CauseLink { pub tick: u64, pub rule: &'static str, pub detail: String,}
impl CauseLink { pub fn new(tick: u64, rule: &'static str, detail: impl Into<String>) -> Self { Self { tick, rule, detail: detail.into(), } }}
/// Ordered record of what happened, oldest first.#[derive(Clone, Debug, Default)]pub struct CauseChain { links: Vec<CauseLink>,}
impl CauseChain { pub fn new() -> Self { Self::default() }
pub fn push(&mut self, link: CauseLink) { self.links.push(link); }
/// Reserve cause capacity before an atomic multi-link transaction mutates. pub(crate) fn try_reserve( &mut self, additional: usize, ) -> Result<(), std::collections::TryReserveError> { self.links.try_reserve(additional) }
/// Links in canonical occurrence order (oldest first). pub fn links(&self) -> &[CauseLink] { &self.links }
pub fn is_empty(&self) -> bool { self.links.is_empty() }
pub fn len(&self) -> usize { self.links.len() }
/// NetHack-voice epitaph fragment, e.g. /// "Slain by own cleverness, via falling boulder, while overburdened". pub fn epitaph(&self) -> String { if self.links.is_empty() { return "Died without witnesses, which is also a story.".to_string(); } self.links .iter() .map(|l| l.detail.clone()) .collect::<Vec<_>>() .join(", via ") }}
#[cfg(test)]mod tests { use super::*;
#[test] fn epitaph_joins_chain() { let mut c = CauseChain::new(); c.push(CauseLink::new(1, "gravity", "own cleverness")); c.push(CauseLink::new(2, "gravity", "falling boulder")); assert!(c.epitaph().contains("falling boulder")); }}