summaryrefslogtreecommitdiff
path: root/src/names/artifact.rs
diff options
context:
space:
mode:
authorskylar <me@casper>2026-11-10 06:50:08 -0800
committerskylar <me@casper>2026-11-10 06:50:08 -0800
commitd36c54d996f3c14ae811312dbbe621e12a39edde (patch)
tree1807134323479ac90bf69d28e410a7f70cb235a1 /src/names/artifact.rs
Orrery: game loop, name generator and derelict dungeons
An ASCII sci-fi-fantasy game for the terminal, built on ratatui. - Game loop with a fixed 30 Hz tick and a stack of scenes; the kitty keyboard protocol is turned on where the terminal supports it, so later real-time scenes can tell when a key is held. - Stable hierarchical seeds: the whole universe derives from one u64, with tests pinning the exact outputs so old seeds keep working. - Name generator with four cultures, each with its own syllables and templates, plus unidentified/true names for artifacts. - Title screen with an animated orrery, and a name forge for browsing generated names. - Derelict ships to board: ship-shaped maps with an engine room, spine corridor, side rooms and bridge; symmetric shadowcasting sight; monsters that wake on sight and hunt; loot carried out through the airlock goes into the hold. - `orrery names` and `orrery ship` print the generators' output without the TUI, for tuning. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'src/names/artifact.rs')
-rw-r--r--src/names/artifact.rs69
1 files changed, 69 insertions, 0 deletions
diff --git a/src/names/artifact.rs b/src/names/artifact.rs
new file mode 100644
index 0000000..af24b3d
--- /dev/null
+++ b/src/names/artifact.rs
@@ -0,0 +1,69 @@
+//! Artifact names: what a thing looks like when you find it, and what it's
+//! called once a scholar has told you what it is.
+
+use rand::RngExt;
+
+use super::{Culture, pick};
+use crate::seed::Rng;
+
+#[derive(Clone, Debug)]
+pub struct Artifact {
+ /// What you see when you find it: "a humming ochre lattice".
+ pub unidentified: String,
+ /// Its true name: "the Lacquered Orrery of Teshemond".
+ pub true_name: String,
+}
+
+pub fn artifact(rng: &mut Rng) -> Artifact {
+ let look = format!("{} {} {}", pick(QUALITIES, rng), pick(COLOURS, rng), pick(SHAPES, rng));
+ let article = if look.starts_with(['a', 'e', 'i', 'o', 'u']) { "an" } else { "a" };
+ let unidentified = format!("{article} {look}");
+
+ let object = pick(OBJECTS, rng);
+ let culture = Culture::ALL[rng.random_range(..Culture::ALL.len())];
+ let true_name = match rng.random_range(0..5) {
+ 0 => format!("the {} {object} of {}", pick(MATERIALS, rng), culture.word(rng)),
+ 1 => format!("the {object} of {}", culture.place(rng)),
+ 2 => format!("{}'s {object}", culture.word(rng)),
+ 3 => format!("the {} {object}", pick(EPITHETS, rng)),
+ _ => format!("the {object} {}", pick(CLAUSES, rng)),
+ };
+ Artifact { unidentified, true_name }
+}
+
+const QUALITIES: &[&str] = &[
+ "humming", "warm", "weightless", "faintly singing", "ice-cold", "flickering", "whispering",
+ "slowly turning", "perfectly still", "pulsing", "dust-caked", "oddly heavy", "tarnished",
+ "ticking", "breathing",
+];
+
+const COLOURS: &[&str] = &[
+ "ochre", "verdigris", "bone-white", "umber", "cerulean", "oxblood", "iridescent", "smoke-grey",
+ "jet-black", "saffron", "rust-red", "pearlescent", "cobalt",
+];
+
+const SHAPES: &[&str] = &[
+ "lattice", "spindle", "disc", "knot", "sphere", "prism", "coil", "shard", "ring", "cube",
+ "cylinder", "helix", "lens", "rod", "tessera",
+];
+
+const MATERIALS: &[&str] = &[
+ "Saltglass", "Black-Iron", "Lacquered", "Bone", "Star-Ivory", "Verdigris", "Voidsteel",
+ "Smoked-Glass", "Amber", "Obsidian", "Gilt", "Quicksilver",
+];
+
+const OBJECTS: &[&str] = &[
+ "Orrery", "Reliquary", "Astrolabe", "Censer", "Lattice", "Mask", "Crown", "Key", "Sigil",
+ "Codex", "Lens", "Spindle", "Compass", "Chalice", "Engine", "Bell", "Heart", "Mirror", "Loom",
+];
+
+const EPITHETS: &[&str] = &[
+ "Weeping", "Ninth", "Hollow", "Unspoken", "Last", "Sleeping", "Burning", "Patient", "Seventh",
+ "Silent", "Drowned", "Unfinished", "Forgotten", "Inverted",
+];
+
+const CLAUSES: &[&str] = &[
+ "That Remembers", "That Was Promised", "Which Does Not Turn", "That Sings at Dusk",
+ "That Counts the Dead", "That Opens Inward", "That Waits", "of Unmaking", "of Seven Silences",
+ "Beneath the Sun",
+];