From 53a026da62b08270c3a3692cae456ff65aa53825 Mon Sep 17 00:00:00 2001 From: Hikari Date: Wed, 15 Apr 2026 19:27:59 -0700 Subject: [PATCH] =?UTF-8?q?feat:=20complete=20vampire=20expansion=20chunk?= =?UTF-8?q?=202=20=E2=80=94=20exploration=20areas?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds vampireExplorations.ts with 72 areas across all 18 vampire zones (4 per zone), each with descriptions, events, material drops, and scaled durations. Also fixes a TypeScript double-cast error in debug.ts and marks chunk 2 complete in vampire.md. --- apps/api/src/data/vampireExplorations.ts | 1758 ++++++++++++++++++++++ apps/api/src/routes/debug.ts | 4 +- vampire-explorations.md | 58 + vampire.md | 5 +- 4 files changed, 1821 insertions(+), 4 deletions(-) create mode 100644 apps/api/src/data/vampireExplorations.ts create mode 100644 vampire-explorations.md diff --git a/apps/api/src/data/vampireExplorations.ts b/apps/api/src/data/vampireExplorations.ts new file mode 100644 index 0000000..bf935ee --- /dev/null +++ b/apps/api/src/data/vampireExplorations.ts @@ -0,0 +1,1758 @@ +/** + * @file Game data definitions. + * @copyright nhcarrigan + * @license Naomi's Public License + * @author Naomi Carrigan + */ + +/* eslint-disable max-lines -- Data file */ +/* eslint-disable stylistic/max-len -- Data content */ +import type { VampireExplorationArea } from "@elysium/types"; + +export const defaultVampireExplorationAreas: Array = [ + // ── Haunted Catacombs ───────────────────────────────────────────────────── + { + description: "A collapsed funeral chamber where the ancient dead rest in crumbling alcoves. Bone dust coats every surface, and the air is thick with the smell of old stone and older blood.", + durationSeconds: 30, + events: [ + { + effect: { amount: 50, type: "blood_gain" }, + id: "bone_chapel_seeping_walls", + text: "Your thralls find fresh blood seeping from a crack in the chapel wall — a mortal who wandered in and met the dark. Not a drop is wasted.", + }, + { + effect: { fraction: 0.03, type: "thrall_loss" }, + id: "bone_chapel_collapse", + text: "A section of the ceiling gives way without warning. Several thralls are buried before the others can pull back.", + }, + ], + id: "bone_chapel", + name: "The Bone Chapel", + possibleMaterials: [ + { materialId: "bone_dust", maxQuantity: 3, minQuantity: 1, weight: 5 }, + { materialId: "grave_essence", maxQuantity: 2, minQuantity: 1, weight: 3 }, + ], + zoneId: "vampire_haunted_catacombs", + }, + { + description: "Row upon row of sealed burial niches line these tunnels, each one marked with a name no living tongue remembers. Something older than memory lingers between them.", + durationSeconds: 60, + events: [ + { + effect: { amount: 150, type: "blood_gain" }, + id: "dusty_crypts_offering", + text: "One niche has been freshly opened from the inside. Whatever was placed there in tribute is still blood-warm. Your thralls bring it to you without question.", + }, + { + effect: { amount: 40, type: "blood_loss" }, + id: "dusty_crypts_shade", + text: "A lingering shade lashes out at the nearest thrall, drawing ichor-tainted blood before it disperses into the dark.", + }, + ], + id: "dusty_crypts", + name: "The Dusty Crypts", + possibleMaterials: [ + { materialId: "bone_dust", maxQuantity: 4, minQuantity: 2, weight: 5 }, + { materialId: "catacomb_ash", maxQuantity: 3, minQuantity: 1, weight: 4 }, + { materialId: "grave_essence", maxQuantity: 2, minQuantity: 1, weight: 2 }, + ], + zoneId: "vampire_haunted_catacombs", + }, + { + description: "A vast underground hall lined with stacked bones arranged into grotesque patterns by some forgotten custodian. The walls seem to breathe.", + durationSeconds: 90, + events: [ + { + effect: { materialId: "grave_essence", quantity: 2, type: "dark_material_gain" }, + id: "ossuary_hall_resonance", + text: "The bones vibrate at a frequency your thralls can feel in their chests. Grave essence pools at the base of the walls like condensation.", + }, + { + effect: { fraction: 0.05, type: "thrall_loss" }, + id: "ossuary_hall_guardian", + text: "The hall's custodian has not fully died. It rises from the bone-pile and tears through a cluster of your thralls before your eldest can put it back down.", + }, + ], + id: "ossuary_hall", + name: "The Ossuary Hall", + possibleMaterials: [ + { materialId: "grave_essence", maxQuantity: 4, minQuantity: 2, weight: 5 }, + { materialId: "bone_dust", maxQuantity: 5, minQuantity: 2, weight: 4 }, + { materialId: "catacomb_ash", maxQuantity: 3, minQuantity: 1, weight: 3 }, + ], + zoneId: "vampire_haunted_catacombs", + }, + { + description: "The deepest reachable chamber in the catacombs, sealed for centuries by iron doors and older wards. Whatever was locked inside has long since stopped trying to get out.", + durationSeconds: 120, + events: [ + { + effect: { amount: 600, type: "blood_gain" }, + id: "deep_vault_cache", + text: "Preserved behind the ancient seals, your thralls discover a cache of blood vials — a vampire hoard from before the sealing. Most are still potent.", + }, + { + effect: { amount: 150, type: "blood_loss" }, + id: "deep_vault_ward", + text: "One of the old wards activates as your thralls breach the inner sanctum. The arcane drain leaves several of them hollow-eyed and shaking.", + }, + ], + id: "deep_vault", + name: "The Deep Vault", + possibleMaterials: [ + { materialId: "catacomb_ash", maxQuantity: 5, minQuantity: 2, weight: 5 }, + { materialId: "grave_essence", maxQuantity: 4, minQuantity: 2, weight: 4 }, + { materialId: "bone_dust", maxQuantity: 6, minQuantity: 3, weight: 3 }, + ], + zoneId: "vampire_haunted_catacombs", + }, + + // ── Blood Mire ──────────────────────────────────────────────────────────── + { + description: "The outermost edge of the mire, where the ground turns soft and the water runs red at dusk. Easy hunting, if you do not mind wet feet.", + durationSeconds: 45, + events: [ + { + effect: { amount: 100, type: "blood_gain" }, + id: "shallow_fens_hunt", + text: "A mortal fisherman lingers past sunset, hoping for one last catch. Your thralls oblige. His catch becomes yours.", + }, + { + effect: { fraction: 0.03, type: "thrall_loss" }, + id: "shallow_fens_quicksand", + text: "The ground gives way beneath a cluster of thralls. The mire takes two before the others drag themselves free.", + }, + ], + id: "shallow_fens", + name: "The Shallow Fens", + possibleMaterials: [ + { materialId: "mire_sludge", maxQuantity: 3, minQuantity: 1, weight: 5 }, + { materialId: "blood_moss", maxQuantity: 2, minQuantity: 1, weight: 3 }, + ], + zoneId: "vampire_blood_mire", + }, + { + description: "Channels of dark water choked with crimson reeds that drink from the blood-saturated soil. Navigating them requires patience your thralls are still learning.", + durationSeconds: 90, + events: [ + { + effect: { materialId: "crimson_reed", quantity: 2, type: "dark_material_gain" }, + id: "reed_channels_harvest", + text: "The reeds are thick and ready. Your thralls cut them at the base, drawing out the red-tinged fluid stored in their cores.", + }, + { + effect: { amount: 60, type: "blood_loss" }, + id: "reed_channels_leech_swarm", + text: "A swarm of blood-leeches rises from the channel floor — small, but numerous. Several thralls are drained before they can retreat to dry land.", + }, + ], + id: "reed_channels", + name: "The Reed Channels", + possibleMaterials: [ + { materialId: "crimson_reed", maxQuantity: 4, minQuantity: 2, weight: 5 }, + { materialId: "blood_moss", maxQuantity: 3, minQuantity: 1, weight: 4 }, + { materialId: "mire_sludge", maxQuantity: 3, minQuantity: 1, weight: 3 }, + ], + zoneId: "vampire_blood_mire", + }, + { + description: "The heart of the mire, where the water no longer moves and the bog has absorbed decades of blood into its soil. Everything here smells of iron and rot.", + durationSeconds: 135, + events: [ + { + effect: { amount: 500, type: "blood_gain" }, + id: "crimson_bog_extraction", + text: "Your thralls press blood-moss into collection cloths and wring them over vessels. The yield is remarkable — the bog has been collecting for years.", + }, + { + effect: { fraction: 0.05, type: "thrall_loss" }, + id: "crimson_bog_feral", + text: "Something feral and half-formed drags itself from the bog — a thrall that went in years ago and never came back. Your own do not hesitate. They should.", + }, + ], + id: "crimson_bog", + name: "The Crimson Bog", + possibleMaterials: [ + { materialId: "blood_moss", maxQuantity: 5, minQuantity: 2, weight: 5 }, + { materialId: "mire_sludge", maxQuantity: 5, minQuantity: 2, weight: 4 }, + { materialId: "crimson_reed", maxQuantity: 4, minQuantity: 2, weight: 3 }, + ], + zoneId: "vampire_blood_mire", + }, + { + description: "The lowest point of the mire, where the ground gives way entirely to a sunken pool of near-black water. What lies at the bottom has never been retrieved. Until now.", + durationSeconds: 180, + events: [ + { + effect: { amount: 1000, type: "blood_gain" }, + id: "sanguine_depths_haul", + text: "Your best thralls dive and return with their arms full of blood-soaked relics from the pool's floor — offerings from decades of mire-cultists. A windfall.", + }, + { + effect: { amount: 250, type: "blood_loss" }, + id: "sanguine_depths_pressure", + text: "The depths exert a supernatural pressure on your thralls. Three surface with cracked ribs and cracked resolve — their blood runs freely before you can get them stable.", + }, + ], + id: "sanguine_depths", + name: "The Sanguine Depths", + possibleMaterials: [ + { materialId: "mire_sludge", maxQuantity: 6, minQuantity: 3, weight: 5 }, + { materialId: "blood_moss", maxQuantity: 6, minQuantity: 3, weight: 4 }, + { materialId: "crimson_reed", maxQuantity: 5, minQuantity: 2, weight: 3 }, + ], + zoneId: "vampire_blood_mire", + }, + + // ── Obsidian Keep ───────────────────────────────────────────────────────── + { + description: "The outermost gate of the keep, where the obsidian walls begin and the guards — mortal and otherwise — maintain their first and last easy watch.", + durationSeconds: 60, + events: [ + { + effect: { amount: 200, type: "blood_gain" }, + id: "gatehouse_toll", + text: "The gate guards have been collecting a toll in blood for months — a private arrangement with something inside. Your thralls collect on their behalf. Permanently.", + }, + { + effect: { fraction: 0.04, type: "thrall_loss" }, + id: "gatehouse_alarm", + text: "One of the guards triggers an alarm rune before your thralls can stop them. The response is swift. You lose several before the rune is destroyed.", + }, + ], + id: "gatehouse", + name: "The Gatehouse", + possibleMaterials: [ + { materialId: "obsidian_chip", maxQuantity: 3, minQuantity: 1, weight: 5 }, + { materialId: "iron_shaving", maxQuantity: 2, minQuantity: 1, weight: 3 }, + ], + zoneId: "vampire_obsidian_keep", + }, + { + description: "The curtain walls of the keep, built from obsidian quarried under moonlight by those who knew what they were building. The stone holds memory.", + durationSeconds: 120, + events: [ + { + effect: { materialId: "obsidian_chip", quantity: 3, type: "dark_material_gain" }, + id: "outer_walls_harvest", + text: "Your thralls chip at the walls with iron tools, and the obsidian crumbles into shards that pulse faintly with retained warmth. You bag them carefully.", + }, + { + effect: { amount: 100, type: "blood_loss" }, + id: "outer_walls_sentinel", + text: "A sentinel construct carved into the wall activates as your thralls reach the inner face. It draws blood before your eldest dismantles it joint by joint.", + }, + ], + id: "outer_walls", + name: "The Outer Walls", + possibleMaterials: [ + { materialId: "obsidian_chip", maxQuantity: 5, minQuantity: 2, weight: 5 }, + { materialId: "keep_mortar", maxQuantity: 3, minQuantity: 1, weight: 4 }, + { materialId: "iron_shaving", maxQuantity: 4, minQuantity: 2, weight: 3 }, + ], + zoneId: "vampire_obsidian_keep", + }, + { + description: "The central chamber of the keep, where its builders once gathered under vaulted obsidian ceilings to conduct their rites. The architecture is still intact. The builders are not.", + durationSeconds: 180, + events: [ + { + effect: { amount: 900, type: "blood_gain" }, + id: "great_hall_ritual_remnants", + text: "The rite-stones in the hall floor still hold the blood of a dozen ancient ceremonies. Your thralls break the stones apart and collect what the obsidian has preserved.", + }, + { + effect: { fraction: 0.06, type: "thrall_loss" }, + id: "great_hall_trap", + text: "The hall's central dais is trapped — a cascade of obsidian spikes that the old masters never disarmed. Your thralls learn this the hard way.", + }, + ], + id: "great_hall", + name: "The Great Hall", + possibleMaterials: [ + { materialId: "keep_mortar", maxQuantity: 5, minQuantity: 2, weight: 5 }, + { materialId: "obsidian_chip", maxQuantity: 6, minQuantity: 3, weight: 4 }, + { materialId: "iron_shaving", maxQuantity: 5, minQuantity: 2, weight: 3 }, + ], + zoneId: "vampire_obsidian_keep", + }, + { + description: "The uppermost tower of the keep, built entirely from a single vein of black volcanic glass. From here, on a clear night, you can see the edge of every zone you have claimed.", + durationSeconds: 240, + events: [ + { + effect: { amount: 1800, type: "blood_gain" }, + id: "black_spire_vault", + text: "At the spire's peak, your thralls find the keep's final treasury — sealed in a chamber of solid obsidian, untouched since its builders fell. It is worth the climb.", + }, + { + effect: { amount: 450, type: "blood_loss" }, + id: "black_spire_wind", + text: "The spire channels wind into something sharp and screaming. Several thralls lose their footing on the outer face. You feel each one go.", + }, + ], + id: "black_spire", + name: "The Black Spire", + possibleMaterials: [ + { materialId: "obsidian_chip", maxQuantity: 7, minQuantity: 3, weight: 5 }, + { materialId: "keep_mortar", maxQuantity: 6, minQuantity: 3, weight: 4 }, + { materialId: "iron_shaving", maxQuantity: 6, minQuantity: 2, weight: 3 }, + ], + zoneId: "vampire_obsidian_keep", + }, + + // ── Crimson Citadel ─────────────────────────────────────────────────────── + { + description: "The outer gate of the citadel, forged from blood bronze and flanked by statues of former lords whose eyes still track movement. A well-travelled entrance. Well-guarded.", + durationSeconds: 75, + events: [ + { + effect: { amount: 300, type: "blood_gain" }, + id: "bronze_gate_tribute", + text: "The gate-keeper collects blood tribute from all who pass. Your thralls relieve them of the day's collection without much ceremony.", + }, + { + effect: { fraction: 0.04, type: "thrall_loss" }, + id: "bronze_gate_statues", + text: "The statues are not decorative. Two thralls are caught in their grip before the others learn to keep their distance.", + }, + ], + id: "bronze_gate", + name: "The Bronze Gate", + possibleMaterials: [ + { materialId: "blood_bronze", maxQuantity: 3, minQuantity: 1, weight: 5 }, + { materialId: "citadel_stone", maxQuantity: 2, minQuantity: 1, weight: 3 }, + ], + zoneId: "vampire_crimson_citadel", + }, + { + description: "The residential wing of the citadel, draped in crimson silk and furnished for lords who expected to live forever. Some of them still do.", + durationSeconds: 150, + events: [ + { + effect: { materialId: "crimson_silk", quantity: 3, type: "dark_material_gain" }, + id: "silk_quarters_drapes", + text: "The silk curtains are soaked through — decades of ambient blood have saturated the fibres. Your thralls cut them down and wring them out.", + }, + { + effect: { amount: 200, type: "blood_loss" }, + id: "silk_quarters_resident", + text: "One of the citadel's original lords is still in residence. Diminished, but territorial. He takes payment in blood before he lets your thralls pass.", + }, + ], + id: "silk_quarters", + name: "The Silk Quarters", + possibleMaterials: [ + { materialId: "crimson_silk", maxQuantity: 5, minQuantity: 2, weight: 5 }, + { materialId: "blood_bronze", maxQuantity: 4, minQuantity: 2, weight: 4 }, + { materialId: "citadel_stone", maxQuantity: 3, minQuantity: 1, weight: 2 }, + ], + zoneId: "vampire_crimson_citadel", + }, + { + description: "Deep in the citadel's undercroft, a forge still burns with a flame no mortal lit. The blood bronze used to build these walls was smelted here, and the furnace has never gone cold.", + durationSeconds: 225, + events: [ + { + effect: { amount: 1500, type: "blood_gain" }, + id: "blood_forge_reserves", + text: "The forge's cooling vats are still full — blood bronze in liquid form, never poured. Your thralls tap the vats and carry what they can.", + }, + { + effect: { fraction: 0.05, type: "thrall_loss" }, + id: "blood_forge_flame", + text: "The forge flame is not merely hot — it hungers. Several thralls stray too close to the core vents and do not step back in time.", + }, + ], + id: "blood_forge", + name: "The Blood Forge", + possibleMaterials: [ + { materialId: "blood_bronze", maxQuantity: 6, minQuantity: 3, weight: 5 }, + { materialId: "citadel_stone", maxQuantity: 5, minQuantity: 2, weight: 4 }, + { materialId: "crimson_silk", maxQuantity: 4, minQuantity: 2, weight: 3 }, + ], + zoneId: "vampire_crimson_citadel", + }, + { + description: "The seat of power at the citadel's heart — a throne carved from a single block of blood-red stone, still warm. Whoever sat here last has not been gone long.", + durationSeconds: 300, + events: [ + { + effect: { amount: 3000, type: "blood_gain" }, + id: "crimson_throne_treasury", + text: "Beneath the throne dais, your thralls find the citadel lord's private reserve — centuries of collected tribute sealed under flagstone. A staggering sum.", + }, + { + effect: { amount: 750, type: "blood_loss" }, + id: "crimson_throne_curse", + text: "The throne is warded against usurpers. The curse does not kill — it just drinks. Your thralls drag themselves away lighter than they entered.", + }, + ], + id: "crimson_throne", + name: "The Crimson Throne", + possibleMaterials: [ + { materialId: "citadel_stone", maxQuantity: 7, minQuantity: 3, weight: 5 }, + { materialId: "blood_bronze", maxQuantity: 6, minQuantity: 3, weight: 4 }, + { materialId: "crimson_silk", maxQuantity: 5, minQuantity: 2, weight: 3 }, + ], + zoneId: "vampire_crimson_citadel", + }, + + // ── Shadow Court ────────────────────────────────────────────────────────── + { + description: "The waiting room of the Shadow Court, where petitioners once sat in silence and shadows pooled at midday. The silence has never left.", + durationSeconds: 90, + events: [ + { + effect: { amount: 450, type: "blood_gain" }, + id: "antechamber_petitioners", + text: "The petitioners never left either. Your thralls find them still waiting — patient, hollow, blood-full. The Court took their vitality as a sitting fee.", + }, + { + effect: { fraction: 0.04, type: "thrall_loss" }, + id: "antechamber_shadow_pull", + text: "The shadows in the antechamber are not passive. They pull three of your thralls into the walls and do not return them whole.", + }, + ], + id: "antechamber", + name: "The Antechamber", + possibleMaterials: [ + { materialId: "shadow_thread", maxQuantity: 3, minQuantity: 1, weight: 5 }, + { materialId: "court_wax", maxQuantity: 2, minQuantity: 1, weight: 3 }, + ], + zoneId: "vampire_shadow_court", + }, + { + description: "A vast archive where the Court recorded every whisper ever spoken within its walls — sealed in wax, transcribed in ink that never fades. Knowledge is power here, and power has a price.", + durationSeconds: 180, + events: [ + { + effect: { materialId: "whisper_ink", quantity: 3, type: "dark_material_gain" }, + id: "ink_library_harvest", + text: "The inkwells are never empty. Your thralls fill vials from the wells directly — each one carries the faint echo of something whispered long ago.", + }, + { + effect: { amount: 300, type: "blood_loss" }, + id: "ink_library_curator", + text: "The library's curator objects to unsanctioned access. It does not have a body anymore, but it has enough presence to make several of your thralls bleed for the intrusion.", + }, + ], + id: "ink_library", + name: "The Ink Library", + possibleMaterials: [ + { materialId: "whisper_ink", maxQuantity: 5, minQuantity: 2, weight: 5 }, + { materialId: "shadow_thread", maxQuantity: 4, minQuantity: 2, weight: 4 }, + { materialId: "court_wax", maxQuantity: 3, minQuantity: 1, weight: 3 }, + ], + zoneId: "vampire_shadow_court", + }, + { + description: "The ritual heart of the Court, where candles of black wax have burned for decades without ever shortening. The light they cast reveals things better left unseen.", + durationSeconds: 270, + events: [ + { + effect: { amount: 2200, type: "blood_gain" }, + id: "wax_sanctum_ritual", + text: "The candles are burning blood, not tallow. Your thralls carefully tilt the holders and collect what has pooled in the base of each — decades of slow accumulation.", + }, + { + effect: { fraction: 0.06, type: "thrall_loss" }, + id: "wax_sanctum_vision", + text: "The light shows your thralls something they were not meant to see. Several simply stop — standing in the sanctum, eyes open, unseeing. You cannot bring them back.", + }, + ], + id: "wax_sanctum", + name: "The Wax Sanctum", + possibleMaterials: [ + { materialId: "court_wax", maxQuantity: 6, minQuantity: 3, weight: 5 }, + { materialId: "whisper_ink", maxQuantity: 5, minQuantity: 2, weight: 4 }, + { materialId: "shadow_thread", maxQuantity: 5, minQuantity: 2, weight: 3 }, + ], + zoneId: "vampire_shadow_court", + }, + { + description: "The Court's innermost chamber, where every whisper ever collected returns as an echo. The throne here is not a seat of power — it is a seat of listening. What it hears, it keeps.", + durationSeconds: 360, + events: [ + { + effect: { amount: 4500, type: "blood_gain" }, + id: "throne_of_whispers_resonance", + text: "The throne amplifies everything — including the heartbeats of the offerings left at its base. Your thralls collect them carefully, filling vessel after vessel with resonance-thickened blood.", + }, + { + effect: { amount: 1200, type: "blood_loss" }, + id: "throne_of_whispers_demand", + text: "The throne demands a whisper in return. Your thralls do not know what was taken — only that they leave a little less themselves than they arrived.", + }, + ], + id: "throne_of_whispers", + name: "The Throne of Whispers", + possibleMaterials: [ + { materialId: "shadow_thread", maxQuantity: 7, minQuantity: 3, weight: 5 }, + { materialId: "court_wax", maxQuantity: 6, minQuantity: 3, weight: 4 }, + { materialId: "whisper_ink", maxQuantity: 6, minQuantity: 2, weight: 3 }, + ], + zoneId: "vampire_shadow_court", + }, + + // ── Plague Ossuary ──────────────────────────────────────────────────────── + { + description: "The entrance to the ossuary, where plague-dead were brought centuries ago and never properly interred. The halls smell of ash and something sweeter, and worse.", + durationSeconds: 105, + events: [ + { + effect: { amount: 600, type: "blood_gain" }, + id: "charnel_entry_stockpile", + text: "The entry hall was used as a staging area — blood drawn from the plague-dead before disposal, stored in sealed urns. Morbid, but your thralls do not object.", + }, + { + effect: { fraction: 0.04, type: "thrall_loss" }, + id: "charnel_entry_contagion", + text: "The plague left something in the air. Several of your thralls breathe too deeply and begin to turn grey at the edges. You quarantine them. They do not recover.", + }, + ], + id: "charnel_entry", + name: "The Charnel Entry", + possibleMaterials: [ + { materialId: "plague_ash", maxQuantity: 3, minQuantity: 1, weight: 5 }, + { materialId: "infected_bone", maxQuantity: 2, minQuantity: 1, weight: 3 }, + ], + zoneId: "vampire_plague_ossuary", + }, + { + description: "Open pits where the bodies were burned when the ossuary filled — the ash here is deep enough to sink to the knee. Nothing from the pits should still be moving.", + durationSeconds: 210, + events: [ + { + effect: { materialId: "plague_ash", quantity: 4, type: "dark_material_gain" }, + id: "ash_pits_harvest", + text: "The ash is rich with preserved vitality — whatever the plague took from the bodies, the fire concentrated it. Your thralls scoop it into sacks with their bare hands.", + }, + { + effect: { amount: 400, type: "blood_loss" }, + id: "ash_pits_risen", + text: "Something that should not be moving is moving. The ash-dead are slow, but there are many of them, and they remember how to bite.", + }, + ], + id: "ash_pits", + name: "The Ash Pits", + possibleMaterials: [ + { materialId: "plague_ash", maxQuantity: 6, minQuantity: 3, weight: 5 }, + { materialId: "infected_bone", maxQuantity: 4, minQuantity: 2, weight: 4 }, + { materialId: "ossuary_resin", maxQuantity: 3, minQuantity: 1, weight: 3 }, + ], + zoneId: "vampire_plague_ossuary", + }, + { + description: "Sealed chambers deep in the ossuary where the plague's most potent victims were locked away in resin-hardened sarcophagi. The resin has held. Mostly.", + durationSeconds: 315, + events: [ + { + effect: { amount: 3000, type: "blood_gain" }, + id: "resin_vaults_extraction", + text: "The resin sarcophagi have been slowly concentrating the blood of their occupants for centuries. Your thralls crack them open with iron tools and drain them methodically.", + }, + { + effect: { fraction: 0.06, type: "thrall_loss" }, + id: "resin_vaults_breach", + text: "One sarcophagus was not properly sealed. What was inside has had centuries to get angry about it. Six thralls do not make it out of the vault.", + }, + ], + id: "resin_vaults", + name: "The Resin Vaults", + possibleMaterials: [ + { materialId: "ossuary_resin", maxQuantity: 6, minQuantity: 3, weight: 5 }, + { materialId: "infected_bone", maxQuantity: 6, minQuantity: 3, weight: 4 }, + { materialId: "plague_ash", maxQuantity: 5, minQuantity: 2, weight: 3 }, + ], + zoneId: "vampire_plague_ossuary", + }, + { + description: "The source — the chamber where the plague began, sealed at the centre of the ossuary and never opened since. The air is wrong here. The stone is wrong. Even the dark is wrong.", + durationSeconds: 420, + events: [ + { + effect: { amount: 6000, type: "blood_gain" }, + id: "plague_heart_reservoir", + text: "At the plague heart's centre, a pool of blood has been collecting since the sealing — fed by every body in the ossuary above. It is vast, cold, and yours.", + }, + { + effect: { amount: 1500, type: "blood_loss" }, + id: "plague_heart_infection", + text: "Even your thralls are not immune to what lives here. The infection moves fast. You lose a significant portion of what you came with just getting them out alive.", + }, + ], + id: "plague_heart", + name: "The Plague Heart", + possibleMaterials: [ + { materialId: "infected_bone", maxQuantity: 7, minQuantity: 4, weight: 5 }, + { materialId: "ossuary_resin", maxQuantity: 7, minQuantity: 3, weight: 4 }, + { materialId: "plague_ash", maxQuantity: 6, minQuantity: 3, weight: 3 }, + ], + zoneId: "vampire_plague_ossuary", + }, + + // ── Ashen Wastes ────────────────────────────────────────────────────────── + { + description: "A vast expanse of volcanic cinder stretching to every horizon, broken only by the occasional column of frozen ash-smoke. Nothing grows here. Nothing needs to.", + durationSeconds: 120, + events: [ + { + effect: { amount: 800, type: "blood_gain" }, + id: "cinder_fields_pilgrim", + text: "A mortal pilgrim crosses the fields at dusk, believing the ash will grant them something. Your thralls intercept them before they reach whatever they were seeking.", + }, + { + effect: { fraction: 0.05, type: "thrall_loss" }, + id: "cinder_fields_sinkhole", + text: "The cinder crust gives way without warning. Several thralls drop into a pocket of superheated ash below. You do not send others to look.", + }, + ], + id: "cinder_fields", + name: "The Cinder Fields", + possibleMaterials: [ + { materialId: "volcanic_ash", maxQuantity: 4, minQuantity: 2, weight: 5 }, + { materialId: "cinder_crystal", maxQuantity: 2, minQuantity: 1, weight: 3 }, + ], + zoneId: "vampire_ashen_wastes", + }, + { + description: "The skeletal remains of a settlement that tried to endure in the wastes. The ash has worn everything soft. What is left is all hard edges and empty windows.", + durationSeconds: 240, + events: [ + { + effect: { materialId: "ashen_cloth", quantity: 3, type: "dark_material_gain" }, + id: "cloth_ruins_salvage", + text: "The residents left in a hurry — clothes still on lines, bedding still on frames. The ash has preserved the cloth in its own way. Your thralls cut it down and roll it tight.", + }, + { + effect: { amount: 500, type: "blood_loss" }, + id: "cloth_ruins_ash_wraith", + text: "Something made of ash and memory still occupies one of the ruins. It has no blood of its own, so it takes some of yours before dispersing.", + }, + ], + id: "cloth_ruins", + name: "The Cloth Ruins", + possibleMaterials: [ + { materialId: "ashen_cloth", maxQuantity: 6, minQuantity: 3, weight: 5 }, + { materialId: "volcanic_ash", maxQuantity: 5, minQuantity: 2, weight: 4 }, + { materialId: "cinder_crystal", maxQuantity: 3, minQuantity: 1, weight: 3 }, + ], + zoneId: "vampire_ashen_wastes", + }, + { + description: "A network of lava tubes beneath the wastes, cooled for centuries but still lined with cinder crystals that pulse faintly with residual heat. The air down here is breathable. Barely.", + durationSeconds: 360, + events: [ + { + effect: { amount: 4000, type: "blood_gain" }, + id: "crystal_caverns_cache", + text: "The crystals have been absorbing heat and blood-vapour for decades — something in their structure condenses it. Your thralls chip them loose and press the liquid from each one.", + }, + { + effect: { fraction: 0.06, type: "thrall_loss" }, + id: "crystal_caverns_gas", + text: "A gas pocket ruptures as your thralls deepen into the tube network. The fumes are not immediately lethal — just slow. You lose several before you can get the rest out.", + }, + ], + id: "crystal_caverns", + name: "The Crystal Caverns", + possibleMaterials: [ + { materialId: "cinder_crystal", maxQuantity: 7, minQuantity: 3, weight: 5 }, + { materialId: "volcanic_ash", maxQuantity: 6, minQuantity: 3, weight: 4 }, + { materialId: "ashen_cloth", maxQuantity: 4, minQuantity: 2, weight: 2 }, + ], + zoneId: "vampire_ashen_wastes", + }, + { + description: "The volcanic vent at the wastes' heart, where the original eruption began and where the heat never fully left. The stone here glows orange at the edges, even now.", + durationSeconds: 480, + events: [ + { + effect: { amount: 8000, type: "blood_gain" }, + id: "smouldering_core_reservoir", + text: "The vent's pressure has been forcing blood upward through capillary cracks for years — pooling in a natural basin just below the surface. Your thralls tap it like a spring.", + }, + { + effect: { amount: 2000, type: "blood_loss" }, + id: "smouldering_core_surge", + text: "The vent surges without warning. The heat is enough to cauterise wounds instantly — which is the only reason you do not lose more. What you lose still stings.", + }, + ], + id: "smouldering_core", + name: "The Smouldering Core", + possibleMaterials: [ + { materialId: "volcanic_ash", maxQuantity: 8, minQuantity: 4, weight: 5 }, + { materialId: "cinder_crystal", maxQuantity: 7, minQuantity: 3, weight: 4 }, + { materialId: "ashen_cloth", maxQuantity: 5, minQuantity: 2, weight: 3 }, + ], + zoneId: "vampire_ashen_wastes", + }, + + // ── The Iron Gaol ───────────────────────────────────────────────────────── + { + description: "Row upon row of iron-barred cells stretching in both directions, each one sealed with a different lock. Most are still occupied.", + durationSeconds: 135, + events: [ + { + effect: { amount: 1000, type: "blood_gain" }, + id: "cell_blocks_prisoners", + text: "The prisoners in the gaol have been kept alive for a long time. Too long, in some cases. Your thralls make efficient work of the cells and return well-fed.", + }, + { + effect: { fraction: 0.05, type: "thrall_loss" }, + id: "cell_blocks_riot", + text: "Several cells open at once — not through your doing. Whatever triggered the release is less important than the immediate problem of what pours out.", + }, + ], + id: "cell_blocks", + name: "The Cell Blocks", + possibleMaterials: [ + { materialId: "iron_rivet", maxQuantity: 4, minQuantity: 2, weight: 5 }, + { materialId: "gaol_stone", maxQuantity: 3, minQuantity: 1, weight: 3 }, + ], + zoneId: "vampire_iron_gaol", + }, + { + description: "A long corridor where chains hang from the ceiling in dense curtains — restraints for things too large or too dangerous for conventional cells. Many are broken.", + durationSeconds: 270, + events: [ + { + effect: { materialId: "chain_link", quantity: 4, type: "dark_material_gain" }, + id: "chain_gallery_salvage", + text: "The chains are iron-forged and blood-tempered — stronger than they look. Your thralls take what they can cut loose, which is considerable.", + }, + { + effect: { amount: 625, type: "blood_loss" }, + id: "chain_gallery_mechanism", + text: "One of the chain mechanisms is still active. It sweeps the corridor without warning and catches three of your thralls before they can clear the range.", + }, + ], + id: "chain_gallery", + name: "The Chain Gallery", + possibleMaterials: [ + { materialId: "chain_link", maxQuantity: 7, minQuantity: 3, weight: 5 }, + { materialId: "iron_rivet", maxQuantity: 5, minQuantity: 2, weight: 4 }, + { materialId: "gaol_stone", maxQuantity: 4, minQuantity: 2, weight: 3 }, + ], + zoneId: "vampire_iron_gaol", + }, + { + description: "The warden's personal quarters — austere, iron-furnished, and sealed from the inside. Whatever the warden was keeping in here, they were keeping it from both directions.", + durationSeconds: 405, + events: [ + { + effect: { amount: 5000, type: "blood_gain" }, + id: "wardens_quarter_ledger", + text: "The warden kept meticulous records — including a private reserve, drawn from the gaol's population over decades, sealed under the floorboards. The ledger describes each entry.", + }, + { + effect: { fraction: 0.07, type: "thrall_loss" }, + id: "wardens_quarter_occupant", + text: "The warden is still here. Not alive, exactly, but present — and they take the intrusion personally. You lose more thralls in this one room than in the entire cell block.", + }, + ], + id: "wardens_quarter", + name: "The Warden's Quarter", + possibleMaterials: [ + { materialId: "gaol_stone", maxQuantity: 7, minQuantity: 3, weight: 5 }, + { materialId: "iron_rivet", maxQuantity: 6, minQuantity: 3, weight: 4 }, + { materialId: "chain_link", maxQuantity: 5, minQuantity: 2, weight: 3 }, + ], + zoneId: "vampire_iron_gaol", + }, + { + description: "The gaol's execution yard — an open courtyard paved with gaol-stone and stained too deep to clean. The block at the centre has never been removed. Neither has the axe.", + durationSeconds: 540, + events: [ + { + effect: { amount: 10000, type: "blood_gain" }, + id: "execution_ground_stones", + text: "Centuries of executions have saturated the gaol-stone to its core. Your thralls crack the paving stones apart and wring blood from them like cloth. The yield is extraordinary.", + }, + { + effect: { amount: 2500, type: "blood_loss" }, + id: "execution_ground_echoes", + text: "The yard is thick with execution-echoes — residual violence that activates when enough blood is disturbed. Your thralls trigger it at the worst possible moment.", + }, + ], + id: "execution_ground", + name: "The Execution Ground", + possibleMaterials: [ + { materialId: "gaol_stone", maxQuantity: 9, minQuantity: 4, weight: 5 }, + { materialId: "iron_rivet", maxQuantity: 7, minQuantity: 3, weight: 4 }, + { materialId: "chain_link", maxQuantity: 6, minQuantity: 3, weight: 3 }, + ], + zoneId: "vampire_iron_gaol", + }, + + // ── Veilborn Hollow ─────────────────────────────────────────────────────── + { + description: "The outermost edge of the hollow, where the veil between the living and the dead thins enough to see through. The light here has a quality that makes distances unreliable.", + durationSeconds: 150, + events: [ + { + effect: { amount: 1200, type: "blood_gain" }, + id: "gossamer_entry_crossing", + text: "Mortals sometimes wander into the hollow looking for lost loved ones. They find something. Your thralls make sure it is useful to you.", + }, + { + effect: { fraction: 0.05, type: "thrall_loss" }, + id: "gossamer_entry_displacement", + text: "The veil is not merely thin — it moves. Several thralls step through without meaning to and cannot find their way back to the same side.", + }, + ], + id: "gossamer_entry", + name: "The Gossamer Entry", + possibleMaterials: [ + { materialId: "veil_thread", maxQuantity: 4, minQuantity: 2, weight: 5 }, + { materialId: "phantom_dust", maxQuantity: 3, minQuantity: 1, weight: 3 }, + ], + zoneId: "vampire_veilborn_hollow", + }, + { + description: "A grove of crystalline formations that grow where the veil touches the earth — hollow inside, resonating with the frequencies of the dead. They are beautiful. They are also listening.", + durationSeconds: 300, + events: [ + { + effect: { materialId: "hollow_crystal", quantity: 4, type: "dark_material_gain" }, + id: "crystal_grove_harvest", + text: "The crystals ring when struck at the right angle and shed their outer layer like a skin. Your thralls work through the grove methodically, collecting each shedding.", + }, + { + effect: { amount: 750, type: "blood_loss" }, + id: "crystal_grove_resonance", + text: "The crystals begin resonating in unison — a frequency that draws blood upward through the skin. Your thralls retreat fast enough to survive, but not without cost.", + }, + ], + id: "crystal_grove", + name: "The Crystal Grove", + possibleMaterials: [ + { materialId: "hollow_crystal", maxQuantity: 7, minQuantity: 3, weight: 5 }, + { materialId: "veil_thread", maxQuantity: 5, minQuantity: 2, weight: 4 }, + { materialId: "phantom_dust", maxQuantity: 4, minQuantity: 2, weight: 3 }, + ], + zoneId: "vampire_veilborn_hollow", + }, + { + description: "A low-lying stretch of the hollow where phantom-dust drifts in permanent suspension and the shapes within it are never quite random. Something is being communicated. You are not sure to whom.", + durationSeconds: 450, + events: [ + { + effect: { amount: 6000, type: "blood_gain" }, + id: "phantom_fen_harvest", + text: "The dust settles when your thralls move through it and condenses into something liquid and dark — phantom-blood, drawn from the dead side of the veil. Cold, but potent.", + }, + { + effect: { fraction: 0.07, type: "thrall_loss" }, + id: "phantom_fen_shapes", + text: "The shapes in the dust are not random. They are specific. Several thralls recognise faces in the suspension and walk toward them. They do not come back.", + }, + ], + id: "phantom_fen", + name: "The Phantom Fen", + possibleMaterials: [ + { materialId: "phantom_dust", maxQuantity: 8, minQuantity: 4, weight: 5 }, + { materialId: "hollow_crystal", maxQuantity: 6, minQuantity: 3, weight: 4 }, + { materialId: "veil_thread", maxQuantity: 6, minQuantity: 3, weight: 3 }, + ], + zoneId: "vampire_veilborn_hollow", + }, + { + description: "The hollow's centre — the point where the veil is not merely thin but absent entirely. Standing here, you can see both sides at once. It is not a comfortable thing to see.", + durationSeconds: 600, + events: [ + { + effect: { amount: 12000, type: "blood_gain" }, + id: "veils_heart_confluence", + text: "At the heart of the hollow, blood from both sides of the veil pools freely — the dead giving back what the living lost, the living giving what the dead still need. You take all of it.", + }, + { + effect: { amount: 3000, type: "blood_loss" }, + id: "veils_heart_toll", + text: "Crossing the absent veil exacts a toll that has nothing to do with wounds. Your thralls return intact but diminished — whatever was taken has not yet been replaced.", + }, + ], + id: "veils_heart", + name: "The Veil's Heart", + possibleMaterials: [ + { materialId: "veil_thread", maxQuantity: 9, minQuantity: 4, weight: 5 }, + { materialId: "hollow_crystal", maxQuantity: 8, minQuantity: 4, weight: 4 }, + { materialId: "phantom_dust", maxQuantity: 8, minQuantity: 3, weight: 3 }, + ], + zoneId: "vampire_veilborn_hollow", + }, + + // ── Moonless Moor ───────────────────────────────────────────────────────── + { + description: "The moor's outermost fringe, where the ground turns soft and the fog rolls in from nowhere at all hours. Even locals stopped crossing it after dark centuries ago.", + durationSeconds: 165, + events: [ + { + effect: { amount: 1500, type: "blood_gain" }, + id: "boggy_fringe_wanderer", + text: "A night wanderer lost in the fog blunders into your thralls before either party is ready. Your thralls recover faster.", + }, + { + effect: { fraction: 0.05, type: "thrall_loss" }, + id: "boggy_fringe_sinkhole", + text: "The bog claims three thralls before the rest learn which patches of ground to avoid. A lesson purchased in the usual currency.", + }, + ], + id: "boggy_fringe", + name: "The Boggy Fringe", + possibleMaterials: [ + { materialId: "moor_peat", maxQuantity: 4, minQuantity: 2, weight: 5 }, + { materialId: "fog_essence", maxQuantity: 3, minQuantity: 1, weight: 3 }, + ], + zoneId: "vampire_moonless_moor", + }, + { + description: "A dense band of fog that sits permanently across the moor's midpoint — thick enough to lose direction, warm enough to suggest something breathing inside it.", + durationSeconds: 330, + events: [ + { + effect: { materialId: "fog_essence", quantity: 4, type: "dark_material_gain" }, + id: "fog_bank_condensation", + text: "The fog condenses on your thralls' collection vessels faster than it should. Something in the suspension is thicker than water. Your thralls fill every container they brought.", + }, + { + effect: { amount: 875, type: "blood_loss" }, + id: "fog_bank_disorientation", + text: "The fog swallows direction entirely. Your thralls circle for hours before finding the edge — arriving back bloodier than they left, though none can explain the wounds.", + }, + ], + id: "fog_bank", + name: "The Fog Bank", + possibleMaterials: [ + { materialId: "fog_essence", maxQuantity: 7, minQuantity: 3, weight: 5 }, + { materialId: "moor_peat", maxQuantity: 6, minQuantity: 3, weight: 4 }, + { materialId: "night_bloom", maxQuantity: 4, minQuantity: 2, weight: 3 }, + ], + zoneId: "vampire_moonless_moor", + }, + { + description: "A clearing deep in the moor where night-blooming flowers grow in perfect concentric circles, as though planted by something with a very specific sense of geometry.", + durationSeconds: 495, + events: [ + { + effect: { amount: 7000, type: "blood_gain" }, + id: "night_bloom_meadow_nectar", + text: "The blooms carry nectar that is not quite nectar — dark, thick, and irresistible to anything with a taste for blood. Your thralls harvest them until the vessels overflow.", + }, + { + effect: { fraction: 0.06, type: "thrall_loss" }, + id: "night_bloom_meadow_guardian", + text: "The geometry of the clearing is a ward, not a garden. Your thralls realise this when the concentric circles begin to close. Not all of them clear the outer ring in time.", + }, + ], + id: "night_bloom_meadow", + name: "The Night Bloom Meadow", + possibleMaterials: [ + { materialId: "night_bloom", maxQuantity: 8, minQuantity: 4, weight: 5 }, + { materialId: "fog_essence", maxQuantity: 6, minQuantity: 3, weight: 4 }, + { materialId: "moor_peat", maxQuantity: 6, minQuantity: 3, weight: 3 }, + ], + zoneId: "vampire_moonless_moor", + }, + { + description: "The absolute centre of the moor — a place where even cloudy nights feel darker, where the fog does not drift but stands, and where the peat is warm underfoot for no reason anyone has ever explained.", + durationSeconds: 660, + events: [ + { + effect: { amount: 14000, type: "blood_gain" }, + id: "moonless_centre_reservoir", + text: "Below the warm peat, your thralls find a buried reservoir — blood pressed into the earth over centuries by the weight above it. The moor has been collecting on your behalf for a very long time.", + }, + { + effect: { amount: 3500, type: "blood_loss" }, + id: "moonless_centre_dark", + text: "The darkness at the centre is not simply the absence of light. It takes. Your thralls emerge diminished in a way that sleep and feeding only partially address.", + }, + ], + id: "moonless_centre", + name: "The Moonless Centre", + possibleMaterials: [ + { materialId: "moor_peat", maxQuantity: 9, minQuantity: 4, weight: 5 }, + { materialId: "night_bloom", maxQuantity: 8, minQuantity: 4, weight: 4 }, + { materialId: "fog_essence", maxQuantity: 7, minQuantity: 3, weight: 3 }, + ], + zoneId: "vampire_moonless_moor", + }, + + // ── The Sunken Crypt ────────────────────────────────────────────────────── + { + description: "The crypt's upper level, half-submerged — the water reached the first-floor windows decades ago and has not receded since. The stone here is slick and the light is wrong.", + durationSeconds: 180, + events: [ + { + effect: { amount: 2000, type: "blood_gain" }, + id: "flooded_entry_surface", + text: "The water carries what was left at the surface when the crypt flooded — personal effects, offering vessels, the contents of broken urns. Your thralls skim the top layer carefully.", + }, + { + effect: { fraction: 0.05, type: "thrall_loss" }, + id: "flooded_entry_current", + text: "An unseen current in the flooded corridors pulls several thralls under before the others can anchor. The crypt keeps what the current takes.", + }, + ], + id: "flooded_entry", + name: "The Flooded Entry", + possibleMaterials: [ + { materialId: "sunken_stone", maxQuantity: 4, minQuantity: 2, weight: 5 }, + { materialId: "deep_amber", maxQuantity: 3, minQuantity: 1, weight: 3 }, + ], + zoneId: "vampire_sunken_crypt", + }, + { + description: "The burial chambers of the crypt's noble occupants — sealed in silk-wrapped sarcophagi that have been submerged long enough for the silk to absorb everything the water carried.", + durationSeconds: 360, + events: [ + { + effect: { materialId: "drowned_silk", quantity: 4, type: "dark_material_gain" }, + id: "silk_tombs_harvest", + text: "Your thralls unwrap the sarcophagi and collect the silk — waterlogged, heavy, and saturated with decades of dissolved blood from the flooded upper chambers.", + }, + { + effect: { amount: 1125, type: "blood_loss" }, + id: "silk_tombs_occupants", + text: "The noble dead do not appreciate being unwrapped. Several sarcophagi open from the inside, and the resulting altercation costs your thralls more than the silk is worth.", + }, + ], + id: "silk_tombs", + name: "The Silk Tombs", + possibleMaterials: [ + { materialId: "drowned_silk", maxQuantity: 7, minQuantity: 3, weight: 5 }, + { materialId: "sunken_stone", maxQuantity: 6, minQuantity: 3, weight: 4 }, + { materialId: "deep_amber", maxQuantity: 4, minQuantity: 2, weight: 3 }, + ], + zoneId: "vampire_sunken_crypt", + }, + { + description: "The deepest dry section of the crypt — a sealed vault where amber-preserved remains have sat in suspended darkness since before the flooding began.", + durationSeconds: 540, + events: [ + { + effect: { amount: 9000, type: "blood_gain" }, + id: "amber_vaults_extraction", + text: "The amber has been concentrating blood from the preserved remains for a century. Your thralls crack each amber casing and press the contents — the yield is extraordinary.", + }, + { + effect: { fraction: 0.07, type: "thrall_loss" }, + id: "amber_vaults_preservation", + text: "Whatever process preserved the amber-dead also preserved their capacity for violence. Three vault occupants are intact enough to be a serious problem.", + }, + ], + id: "amber_vaults", + name: "The Amber Vaults", + possibleMaterials: [ + { materialId: "deep_amber", maxQuantity: 8, minQuantity: 4, weight: 5 }, + { materialId: "drowned_silk", maxQuantity: 6, minQuantity: 3, weight: 4 }, + { materialId: "sunken_stone", maxQuantity: 7, minQuantity: 3, weight: 3 }, + ], + zoneId: "vampire_sunken_crypt", + }, + { + description: "The crypt's lowest and oldest chamber, entirely submerged — accessible only by diving, and only by those who do not need to breathe. What is down here has been waiting a very long time.", + durationSeconds: 720, + events: [ + { + effect: { amount: 18000, type: "blood_gain" }, + id: "deepmost_chamber_trove", + text: "The chamber holds the crypt's founding blood-price — the original offering that consecrated the site. Untouched for centuries. Unmistakably yours now.", + }, + { + effect: { amount: 4500, type: "blood_loss" }, + id: "deepmost_chamber_pressure", + text: "The depth exerts a pressure that is not purely physical. Your thralls surface with cracked vessels and cracked composure. The recovery takes time you can ill afford.", + }, + ], + id: "deepmost_chamber", + name: "The Deepmost Chamber", + possibleMaterials: [ + { materialId: "sunken_stone", maxQuantity: 10, minQuantity: 5, weight: 5 }, + { materialId: "deep_amber", maxQuantity: 9, minQuantity: 4, weight: 4 }, + { materialId: "drowned_silk", maxQuantity: 7, minQuantity: 3, weight: 3 }, + ], + zoneId: "vampire_sunken_crypt", + }, + + // ── Desecrated Sanctum ──────────────────────────────────────────────────── + { + description: "What was once a place of worship, now stripped to the walls — every icon removed, every prayer answered with fire. The marble floor is cracked and the ceiling is open to the sky.", + durationSeconds: 195, + events: [ + { + effect: { amount: 2500, type: "blood_gain" }, + id: "broken_nave_offering", + text: "Blood offerings were left here after the desecration — not worship, but a different kind of devotion. Your thralls collect them from the altar niches without ceremony.", + }, + { + effect: { fraction: 0.05, type: "thrall_loss" }, + id: "broken_nave_ceiling", + text: "The open ceiling is not merely structural damage. Something uses it as an entry point. Several thralls are taken from above before the rest close ranks.", + }, + ], + id: "broken_nave", + name: "The Broken Nave", + possibleMaterials: [ + { materialId: "defiled_marble", maxQuantity: 4, minQuantity: 2, weight: 5 }, + { materialId: "dark_incense", maxQuantity: 3, minQuantity: 1, weight: 3 }, + ], + zoneId: "vampire_desecrated_sanctum", + }, + { + description: "The sanctum's chapel of glass — stained windows shattered inward, their shards still lying where they fell, catching the light in patterns that were never in the original design.", + durationSeconds: 390, + events: [ + { + effect: { materialId: "sanctum_glass", quantity: 4, type: "dark_material_gain" }, + id: "glass_chapel_harvest", + text: "The shards are worth taking — sanctum glass holds whatever light it last absorbed, and this glass absorbed centuries of prayer before the desecration inverted it.", + }, + { + effect: { amount: 1500, type: "blood_loss" }, + id: "glass_chapel_reflection", + text: "The glass reflects something your thralls were not expecting to see. The distraction costs more than the glass is worth — several stand transfixed long enough for the sanctum to notice them.", + }, + ], + id: "glass_chapel", + name: "The Glass Chapel", + possibleMaterials: [ + { materialId: "sanctum_glass", maxQuantity: 7, minQuantity: 3, weight: 5 }, + { materialId: "defiled_marble", maxQuantity: 6, minQuantity: 3, weight: 4 }, + { materialId: "dark_incense", maxQuantity: 5, minQuantity: 2, weight: 3 }, + ], + zoneId: "vampire_desecrated_sanctum", + }, + { + description: "Burial crypts beneath the sanctum where the incense has burned continuously since before the desecration — thick and sweet and wrong. The smoke does not dissipate.", + durationSeconds: 585, + events: [ + { + effect: { amount: 12000, type: "blood_gain" }, + id: "incense_crypts_residue", + text: "The incense smoke has been condensing on the crypt walls for decades, forming a resinous dark residue that your thralls scrape loose. It is potent in ways the original incense was not.", + }, + { + effect: { fraction: 0.07, type: "thrall_loss" }, + id: "incense_crypts_smoke", + text: "The smoke is not merely atmospheric. Your thralls who breathe it — even briefly — are changed in some small, permanent way. Several do not survive the change.", + }, + ], + id: "incense_crypts", + name: "The Incense Crypts", + possibleMaterials: [ + { materialId: "dark_incense", maxQuantity: 9, minQuantity: 4, weight: 5 }, + { materialId: "sanctum_glass", maxQuantity: 7, minQuantity: 3, weight: 4 }, + { materialId: "defiled_marble", maxQuantity: 7, minQuantity: 3, weight: 3 }, + ], + zoneId: "vampire_desecrated_sanctum", + }, + { + description: "The sanctum's inner altar — the focal point of the original desecration, still active, still hungry. Whatever was summoned here did not leave when the ceremony ended.", + durationSeconds: 780, + events: [ + { + effect: { amount: 24000, type: "blood_gain" }, + id: "altar_of_defilement_reserve", + text: "The altar has been collecting since the desecration — blood offered by those who came after, compounding over generations. The reservoir beneath it is staggering. You take it all.", + }, + { + effect: { amount: 6000, type: "blood_loss" }, + id: "altar_of_defilement_tithe", + text: "Whatever remains at the altar demands its tithe before you can leave. It does not ask. It simply takes. Your thralls stagger out significantly lighter than they arrived.", + }, + ], + id: "altar_of_defilement", + name: "The Altar of Defilement", + possibleMaterials: [ + { materialId: "defiled_marble", maxQuantity: 10, minQuantity: 5, weight: 5 }, + { materialId: "dark_incense", maxQuantity: 9, minQuantity: 4, weight: 4 }, + { materialId: "sanctum_glass", maxQuantity: 8, minQuantity: 4, weight: 3 }, + ], + zoneId: "vampire_desecrated_sanctum", + }, + + // ── Carrion Peaks ───────────────────────────────────────────────────────── + { + description: "The lower trails of the peaks, where scavengers have worn paths between the fallen. The carrion is old here — sun-bleached and picked clean — but not entirely without value.", + durationSeconds: 210, + events: [ + { + effect: { amount: 3000, type: "blood_gain" }, + id: "scavenger_trails_cache", + text: "A scavenger's den tucked into the trail-side holds more than bones — they have been collecting blood in sealed pouches from fresh kills for years. Your thralls relieve them of the stockpile.", + }, + { + effect: { fraction: 0.05, type: "thrall_loss" }, + id: "scavenger_trails_ambush", + text: "The scavengers here are not merely animals. Something intelligence-adjacent uses the trails as hunting grounds and catches your rear guard before they can close ranks.", + }, + ], + id: "scavenger_trails", + name: "The Scavenger Trails", + possibleMaterials: [ + { materialId: "carrion_bone", maxQuantity: 5, minQuantity: 2, weight: 5 }, + { materialId: "peak_crystal", maxQuantity: 3, minQuantity: 1, weight: 3 }, + ], + zoneId: "vampire_carrion_peaks", + }, + { + description: "The upper ridges of the peaks, where the stone is shot through with veins of peak crystal that catch the moonlight and scatter it into something that has no business being beautiful up here.", + durationSeconds: 420, + events: [ + { + effect: { materialId: "peak_crystal", quantity: 4, type: "dark_material_gain" }, + id: "crystal_ridges_mining", + text: "The veins run deep and the crystal comes free in large fragments. Your thralls work the ridge-face methodically, filling sacks with pieces that hum faintly under the fingers.", + }, + { + effect: { amount: 1875, type: "blood_loss" }, + id: "crystal_ridges_edge", + text: "The ridges are narrow and the drop is total. Several thralls lose their footing on crystal-slick stone. You do not hear them land.", + }, + ], + id: "crystal_ridges", + name: "The Crystal Ridges", + possibleMaterials: [ + { materialId: "peak_crystal", maxQuantity: 8, minQuantity: 4, weight: 5 }, + { materialId: "carrion_bone", maxQuantity: 7, minQuantity: 3, weight: 4 }, + { materialId: "blood_obsidian",maxQuantity: 4, minQuantity: 2, weight: 3 }, + ], + zoneId: "vampire_carrion_peaks", + }, + { + description: "Vast slopes of accumulated bones — centuries of creatures and people brought to the peaks and left there. The obsidian runs through them like black veins through white marble.", + durationSeconds: 630, + events: [ + { + effect: { amount: 15000, type: "blood_gain" }, + id: "bone_slopes_compression", + text: "The weight of centuries of bone has compressed the lower layers into something almost liquid — the marrow has been pressed free and pooled between the obsidian veins. A remarkable harvest.", + }, + { + effect: { fraction: 0.07, type: "thrall_loss" }, + id: "bone_slopes_avalanche", + text: "The slopes are not stable. A section gives way and carries a significant portion of your thralls down the mountain. Those at the bottom of the slide do not resurface.", + }, + ], + id: "bone_slopes", + name: "The Bone Slopes", + possibleMaterials: [ + { materialId: "carrion_bone", maxQuantity: 10, minQuantity: 5, weight: 5 }, + { materialId: "blood_obsidian",maxQuantity: 7, minQuantity: 3, weight: 4 }, + { materialId: "peak_crystal", maxQuantity: 6, minQuantity: 3, weight: 3 }, + ], + zoneId: "vampire_carrion_peaks", + }, + { + description: "The absolute summit of the peaks — a plateau of pure blood obsidian worn smooth by wind and age. Nothing lives at this altitude. Nothing needs to. The view is extraordinary. The drop is absolute.", + durationSeconds: 840, + events: [ + { + effect: { amount: 30000, type: "blood_gain" }, + id: "obsidian_summit_vein", + text: "The obsidian at the summit is not merely stone — it is a convergence point, and blood has been seeping through it from below for centuries. Your thralls tap the convergence with iron tools and collect until their arms give out.", + }, + { + effect: { amount: 7500, type: "blood_loss" }, + id: "obsidian_summit_wind", + text: "The summit wind is not natural. It strips blood from open wounds faster than they can close. Several thralls bleed out before you can get them below the windline.", + }, + ], + id: "obsidian_summit", + name: "The Obsidian Summit", + possibleMaterials: [ + { materialId: "blood_obsidian",maxQuantity: 11, minQuantity: 5, weight: 5 }, + { materialId: "peak_crystal", maxQuantity: 9, minQuantity: 4, weight: 4 }, + { materialId: "carrion_bone", maxQuantity: 8, minQuantity: 4, weight: 3 }, + ], + zoneId: "vampire_carrion_peaks", + }, + + // ── The Bloodspire ──────────────────────────────────────────────────────── + { + description: "The base of the Bloodspire — a structure that was not built so much as grown, rising from the ground like something the earth decided to extrude. The stone here is warm.", + durationSeconds: 225, + events: [ + { + effect: { amount: 4000, type: "blood_gain" }, + id: "spire_approach_pilgrims", + text: "The spire draws pilgrims who believe it will give them something. It does — in the sense that everything eventually gives. Your thralls collect the tribute left at the base.", + }, + { + effect: { fraction: 0.06, type: "thrall_loss" }, + id: "spire_approach_pull", + text: "The spire exerts something more than gravity on those who approach too quickly. Several thralls are drawn toward the base at a speed they did not choose and do not survive.", + }, + ], + id: "spire_approach", + name: "The Spire Approach", + possibleMaterials: [ + { materialId: "spire_stone", maxQuantity: 5, minQuantity: 2, weight: 5 }, + { materialId: "blood_crystal", maxQuantity: 3, minQuantity: 1, weight: 3 }, + ], + zoneId: "vampire_bloodspire", + }, + { + description: "The interior of the spire's lower levels, where blood crystals grow in clusters from every surface — feeding on whatever the spire draws in through its walls.", + durationSeconds: 450, + events: [ + { + effect: { materialId: "blood_crystal", quantity: 5, type: "dark_material_gain" }, + id: "crystal_veins_harvest", + text: "The crystals shatter cleanly when struck at the base — each one hollow and full of condensed blood. Your thralls fill their vessels from the broken clusters.", + }, + { + effect: { amount: 2500, type: "blood_loss" }, + id: "crystal_veins_feedback", + text: "The crystals are connected. Breaking too many at once triggers a feedback pulse through the walls — it draws blood outward through the skin of anyone in contact with the stone.", + }, + ], + id: "crystal_veins", + name: "The Crystal Veins", + possibleMaterials: [ + { materialId: "blood_crystal", maxQuantity: 9, minQuantity: 4, weight: 5 }, + { materialId: "spire_stone", maxQuantity: 7, minQuantity: 3, weight: 4 }, + { materialId: "ancient_gore", maxQuantity: 5, minQuantity: 2, weight: 3 }, + ], + zoneId: "vampire_bloodspire", + }, + { + description: "Mid-spire chambers where ancient gore has been compressed by the weight of the structure above — dark, dense, and potent with age. The smell is remarkable.", + durationSeconds: 675, + events: [ + { + effect: { amount: 20000, type: "blood_gain" }, + id: "gore_chambers_extraction", + text: "The compression has reduced centuries of accumulated blood to a near-solid mass. Your thralls chip it loose in blocks and melt it down into vessels. The process is efficient and deeply unpleasant.", + }, + { + effect: { fraction: 0.08, type: "thrall_loss" }, + id: "gore_chambers_age", + text: "Something ancient is preserved in the compressed gore — not fully alive, not fully dead, and deeply unhappy about being disturbed. The chamber fight is the worst your thralls have seen.", + }, + ], + id: "gore_chambers", + name: "The Gore Chambers", + possibleMaterials: [ + { materialId: "ancient_gore", maxQuantity: 11, minQuantity: 5, weight: 5 }, + { materialId: "blood_crystal", maxQuantity: 8, minQuantity: 4, weight: 4 }, + { materialId: "spire_stone", maxQuantity: 8, minQuantity: 4, weight: 3 }, + ], + zoneId: "vampire_bloodspire", + }, + { + description: "The summit of the Bloodspire — a needle-point of pure spire stone surrounded by nothing but sky. Up here, the wind carries blood-mist from below, and the horizon curves in a direction it should not.", + durationSeconds: 900, + events: [ + { + effect: { amount: 40000, type: "blood_gain" }, + id: "spire_apex_convergence", + text: "The apex is a convergence of everything the spire has ever drawn in — centuries of accumulated blood-force compressed to a single point. Your thralls tap it with every vessel they carry and still cannot take it all.", + }, + { + effect: { amount: 10000, type: "blood_loss" }, + id: "spire_apex_toll", + text: "The spire demands something in return for the apex. It does not ask — it simply adjusts the balance. Your thralls descend lighter than they climbed, in more than one sense.", + }, + ], + id: "spire_apex", + name: "The Spire Apex", + possibleMaterials: [ + { materialId: "spire_stone", maxQuantity: 12, minQuantity: 5, weight: 5 }, + { materialId: "ancient_gore", maxQuantity: 10, minQuantity: 4, weight: 4 }, + { materialId: "blood_crystal", maxQuantity: 9, minQuantity: 4, weight: 3 }, + ], + zoneId: "vampire_bloodspire", + }, + + // ── Shroud of Eternity ──────────────────────────────────────────────────── + { + description: "The outermost boundary of the Shroud — where time begins to move at a slightly different rate and the light has a quality that makes everything look both older and newer than it is.", + durationSeconds: 240, + events: [ + { + effect: { amount: 5000, type: "blood_gain" }, + id: "shrouds_edge_boundary", + text: "The boundary effect preserves everything it touches — including blood offerings left at the edge by those who sought the Shroud's gift of eternity. Your thralls collect centuries of preserved tribute.", + }, + { + effect: { fraction: 0.05, type: "thrall_loss" }, + id: "shrouds_edge_displacement", + text: "The time differential at the boundary is not merely perceptual. Several thralls step across it and return aged by years in an instant. They do not survive the shock.", + }, + ], + id: "shrouds_edge", + name: "The Shroud's Edge", + possibleMaterials: [ + { materialId: "eternity_thread", maxQuantity: 5, minQuantity: 2, weight: 5 }, + { materialId: "shroud_dust", maxQuantity: 4, minQuantity: 2, weight: 3 }, + ], + zoneId: "vampire_shroud_of_eternity", + }, + { + description: "A grove of ancient trees deep in the Shroud, where timeless amber drips from the bark in slow, golden beads — each one containing something that was old before the Shroud formed.", + durationSeconds: 480, + events: [ + { + effect: { materialId: "timeless_amber", quantity: 5, type: "dark_material_gain" }, + id: "amber_groves_collection", + text: "The amber beads carry whatever they last enveloped — blood, memory, time. Your thralls harvest them from the bark with small knives and store them carefully in padded vessels.", + }, + { + effect: { amount: 3125, type: "blood_loss" }, + id: "amber_groves_preservation", + text: "The amber does not discriminate. Several thralls are caught mid-step in a slow amber extrusion from a split trunk. Freeing them costs your best thralls several hours and most of their blood.", + }, + ], + id: "amber_groves", + name: "The Amber Groves", + possibleMaterials: [ + { materialId: "timeless_amber", maxQuantity: 9, minQuantity: 4, weight: 5 }, + { materialId: "eternity_thread",maxQuantity: 7, minQuantity: 3, weight: 4 }, + { materialId: "shroud_dust", maxQuantity: 6, minQuantity: 3, weight: 3 }, + ], + zoneId: "vampire_shroud_of_eternity", + }, + { + description: "A vast expanse of shroud-dust that has settled into dunes across the Shroud's interior — ancient particulate matter that carries age in every grain. Walking through it feels like walking through accumulated years.", + durationSeconds: 720, + events: [ + { + effect: { amount: 25000, type: "blood_gain" }, + id: "dust_wastes_harvest", + text: "The dust settles into blood like a catalyst — thickening it, concentrating it, making it something more than it was. Your thralls bleed small amounts into collection vessels and wait. The yield is extraordinary.", + }, + { + effect: { fraction: 0.07, type: "thrall_loss" }, + id: "dust_wastes_accumulation", + text: "The dust accumulates faster than your thralls can move through it. Several are buried to the waist, then the chest, then gone. The dunes shift and cover where they stood as though nothing happened.", + }, + ], + id: "dust_wastes", + name: "The Dust Wastes", + possibleMaterials: [ + { materialId: "shroud_dust", maxQuantity: 12, minQuantity: 5, weight: 5 }, + { materialId: "timeless_amber", maxQuantity: 9, minQuantity: 4, weight: 4 }, + { materialId: "eternity_thread",maxQuantity: 8, minQuantity: 4, weight: 3 }, + ], + zoneId: "vampire_shroud_of_eternity", + }, + { + description: "The Shroud's innermost point — where the threads of eternity are visible as literal filaments of light running through the air, and where time does not move in any direction at all.", + durationSeconds: 960, + events: [ + { + effect: { amount: 50000, type: "blood_gain" }, + id: "eternal_weave_confluence", + text: "The threads carry everything — memory, time, blood — in an unbroken loop. Your thralls intercept the loop at a nexus point and draw from it until the vessels shatter from the pressure.", + }, + { + effect: { amount: 12500, type: "blood_loss" }, + id: "eternal_weave_unravelling", + text: "The weave does not take kindly to interception. It unravels your thralls in the same way it unravels everything else — slowly, completely, without malice. Simply the nature of eternity.", + }, + ], + id: "eternal_weave", + name: "The Eternal Weave", + possibleMaterials: [ + { materialId: "eternity_thread",maxQuantity: 13, minQuantity: 6, weight: 5 }, + { materialId: "shroud_dust", maxQuantity: 11, minQuantity: 5, weight: 4 }, + { materialId: "timeless_amber", maxQuantity: 10, minQuantity: 4, weight: 3 }, + ], + zoneId: "vampire_shroud_of_eternity", + }, + + // ── The Abyssal Vault ───────────────────────────────────────────────────── + { + description: "The outer gates of the Vault — sealed by architects who understood what they were locking inside. The vault iron of the doors is centuries old and has never once considered rusting.", + durationSeconds: 255, + events: [ + { + effect: { amount: 6000, type: "blood_gain" }, + id: "vault_gates_tribute", + text: "The architects who sealed the Vault left tribute inside the gate mechanism — an offering to whatever they locked in, to keep it from pushing back. Your thralls relieve the mechanism of its gift.", + }, + { + effect: { fraction: 0.06, type: "thrall_loss" }, + id: "vault_gates_resistance", + text: "The gates push back. Not mechanically — something on the other side applies pressure that has nothing to do with weight. Several thralls are simply not there when the others look back.", + }, + ], + id: "vault_gates", + name: "The Vault Gates", + possibleMaterials: [ + { materialId: "vault_iron", maxQuantity: 5, minQuantity: 2, weight: 5 }, + { materialId: "abyssal_stone", maxQuantity: 4, minQuantity: 2, weight: 3 }, + ], + zoneId: "vampire_abyssal_vault", + }, + { + description: "The deep corridors of the Vault, carved from abyssal stone that absorbs light rather than reflecting it. Void crystals stud the walls like inverted stars.", + durationSeconds: 510, + events: [ + { + effect: { materialId: "void_crystal", quantity: 5, type: "dark_material_gain" }, + id: "abyssal_corridors_harvest", + text: "The void crystals come free with a sound like silence becoming solid. Each one absorbs whatever light touches it — including the faint luminescence of fresh blood. Your thralls collect them in complete darkness.", + }, + { + effect: { amount: 3750, type: "blood_loss" }, + id: "abyssal_corridors_drain", + text: "The abyssal stone draws heat from everything near it. Blood cools faster than it should, and cold blood moves slower. Your thralls lose more in the corridors than they intend to.", + }, + ], + id: "abyssal_corridors", + name: "The Abyssal Corridors", + possibleMaterials: [ + { materialId: "void_crystal", maxQuantity: 10, minQuantity: 4, weight: 5 }, + { materialId: "abyssal_stone", maxQuantity: 8, minQuantity: 4, weight: 4 }, + { materialId: "vault_iron", maxQuantity: 7, minQuantity: 3, weight: 3 }, + ], + zoneId: "vampire_abyssal_vault", + }, + { + description: "The inner sanctum of the Vault — the room that was sealed first and most thoroughly. The abyssal stone here has never seen light. The vault iron fittings are welded, not locked.", + durationSeconds: 765, + events: [ + { + effect: { amount: 30000, type: "blood_gain" }, + id: "inner_sanctum_reserve", + text: "The Vault's purpose was preservation, and it has done its job. Everything sealed inside the inner sanctum is exactly as it was left — including a blood reserve that was vast when new and has only concentrated since.", + }, + { + effect: { fraction: 0.08, type: "thrall_loss" }, + id: "inner_sanctum_occupant", + text: "The sanctum was not empty when it was sealed. Whatever shares the space with the reserve has had centuries of solitude to develop strong feelings about visitors.", + }, + ], + id: "inner_sanctum", + name: "The Inner Sanctum", + possibleMaterials: [ + { materialId: "abyssal_stone", maxQuantity: 12, minQuantity: 5, weight: 5 }, + { materialId: "vault_iron", maxQuantity: 10, minQuantity: 4, weight: 4 }, + { materialId: "void_crystal", maxQuantity: 9, minQuantity: 4, weight: 3 }, + ], + zoneId: "vampire_abyssal_vault", + }, + { + description: "The absolute bottom of the Vault — a chamber below the sanctum that was not in the original design. Whatever is down here dug its own way in, from below, and has been here longer than the Vault itself.", + durationSeconds: 1020, + events: [ + { + effect: { amount: 60000, type: "blood_gain" }, + id: "vault_nadir_convergence", + text: "The Vault's nadir is a blood convergence older than the structure above it. It has been drawing from every source within range for an age. Your thralls tap it carefully and fill every vessel they carry twice over.", + }, + { + effect: { amount: 15000, type: "blood_loss" }, + id: "vault_nadir_presence", + text: "Something at the nadir notices being drawn from. It does not retaliate — it simply equalises. Whatever your thralls gained, it takes a proportionate share back before they can leave.", + }, + ], + id: "vault_nadir", + name: "The Vault Nadir", + possibleMaterials: [ + { materialId: "vault_iron", maxQuantity: 13, minQuantity: 6, weight: 5 }, + { materialId: "void_crystal", maxQuantity: 12, minQuantity: 5, weight: 4 }, + { materialId: "abyssal_stone", maxQuantity: 11, minQuantity: 5, weight: 3 }, + ], + zoneId: "vampire_abyssal_vault", + }, + + // ── Court of Whispers ───────────────────────────────────────────────────── + { + description: "The entrance hall of the Court, where every footstep is recorded in whisper-parchment that lines the walls like wallpaper. You can hear, faintly, every visitor who has ever entered.", + durationSeconds: 270, + events: [ + { + effect: { amount: 8000, type: "blood_gain" }, + id: "entrance_hall_records", + text: "The parchment records more than footsteps. Your thralls peel sections from the walls and wring from them every secret left at the threshold — including blood-prices paid for admission over centuries.", + }, + { + effect: { fraction: 0.06, type: "thrall_loss" }, + id: "entrance_hall_whispers", + text: "The whispers are not merely ambient. Several thralls stop moving, heads tilted, listening to something the others cannot hear. They do not start moving again.", + }, + ], + id: "entrance_hall", + name: "The Entrance Hall", + possibleMaterials: [ + { materialId: "whisper_parchment", maxQuantity: 5, minQuantity: 2, weight: 5 }, + { materialId: "court_crystal", maxQuantity: 4, minQuantity: 2, weight: 3 }, + ], + zoneId: "vampire_court_of_whispers", + }, + { + description: "The Court's chamber of records — walls of court crystal shelving holding silent-ink manuscripts that contain every judgement ever rendered within these walls. The ink does not fade. It waits.", + durationSeconds: 540, + events: [ + { + effect: { materialId: "silent_ink", quantity: 5, type: "dark_material_gain" }, + id: "records_chamber_harvest", + text: "The silent ink is not in the manuscripts — it is in the walls behind the shelves, seeping through the crystal from some deeper source. Your thralls tap the crystal face and collect what runs free.", + }, + { + effect: { amount: 5000, type: "blood_loss" }, + id: "records_chamber_judgement", + text: "The records chamber renders judgement on those who take without leave. The sentence is proportionate, automatic, and delivered without ceremony. Your thralls pay the fine.", + }, + ], + id: "records_chamber", + name: "The Records Chamber", + possibleMaterials: [ + { materialId: "silent_ink", maxQuantity: 10, minQuantity: 4, weight: 5 }, + { materialId: "court_crystal", maxQuantity: 9, minQuantity: 4, weight: 4 }, + { materialId: "whisper_parchment", maxQuantity: 7, minQuantity: 3, weight: 3 }, + ], + zoneId: "vampire_court_of_whispers", + }, + { + description: "The deliberation hall, where the Court's judgements were reached in absolute silence — the court crystal amplifying thought rather than sound. The silence here is structural.", + durationSeconds: 810, + events: [ + { + effect: { amount: 40000, type: "blood_gain" }, + id: "deliberation_hall_amplification", + text: "The court crystals in the hall amplify everything, including the residual blood-force of every deliberation ever conducted. Your thralls attune collection vessels to the crystal frequency and draw directly from the amplified field.", + }, + { + effect: { fraction: 0.08, type: "thrall_loss" }, + id: "deliberation_hall_silence", + text: "The structural silence enforces itself. Thralls who break it — even involuntarily — are silenced by the hall in a more permanent sense. You lose more here than anywhere else in the Court.", + }, + ], + id: "deliberation_hall", + name: "The Deliberation Hall", + possibleMaterials: [ + { materialId: "court_crystal", maxQuantity: 12, minQuantity: 5, weight: 5 }, + { materialId: "silent_ink", maxQuantity: 10, minQuantity: 4, weight: 4 }, + { materialId: "whisper_parchment", maxQuantity: 9, minQuantity: 4, weight: 3 }, + ], + zoneId: "vampire_court_of_whispers", + }, + { + description: "The Court's innermost chamber — the place where whispers become verdicts and verdicts become permanent. The silence here is not empty. It is full, to the point of pressure.", + durationSeconds: 1080, + events: [ + { + effect: { amount: 80000, type: "blood_gain" }, + id: "verdict_chamber_archive", + text: "Every verdict rendered in this chamber left a blood-mark — a drop pressed to parchment as seal and signature. Centuries of verdicts. Your thralls harvest the archive methodically. The yield is staggering.", + }, + { + effect: { amount: 20000, type: "blood_loss" }, + id: "verdict_chamber_sentence", + text: "The chamber renders its own verdict on your intrusion. The sentence is proportionate to what was taken. Your thralls exit having paid it, whether they agreed to or not.", + }, + ], + id: "verdict_chamber", + name: "The Verdict Chamber", + possibleMaterials: [ + { materialId: "whisper_parchment", maxQuantity: 13, minQuantity: 6, weight: 5 }, + { materialId: "court_crystal", maxQuantity: 12, minQuantity: 5, weight: 4 }, + { materialId: "silent_ink", maxQuantity: 11, minQuantity: 5, weight: 3 }, + ], + zoneId: "vampire_court_of_whispers", + }, + + // ── The Eternal Abyss ───────────────────────────────────────────────────── + { + description: "The threshold of the Eternal Abyss — the last border before everything becomes something else entirely. The primordial ash begins here, drifting upward rather than settling.", + durationSeconds: 300, + events: [ + { + effect: { amount: 10000, type: "blood_gain" }, + id: "abyss_threshold_drift", + text: "The upward-drifting ash carries everything that has fallen into the Abyss over the ages — including blood, preserved and concentrated by the long fall. Your thralls collect the ash-fall in upward-facing vessels.", + }, + { + effect: { fraction: 0.06, type: "thrall_loss" }, + id: "abyss_threshold_pull", + text: "The Abyss pulls. Not dramatically — just persistently. Several thralls who stand too long at the threshold find themselves leaning forward in a way they did not choose and cannot correct in time.", + }, + ], + id: "abyss_threshold", + name: "The Abyss Threshold", + possibleMaterials: [ + { materialId: "primordial_ash", maxQuantity: 5, minQuantity: 2, weight: 5 }, + { materialId: "eternal_crystal", maxQuantity: 4, minQuantity: 2, weight: 3 }, + ], + zoneId: "vampire_eternal_abyss", + }, + { + description: "The upper reaches of the Abyss itself — not truly the bottom, but far enough in that up and down begin to lose consensus. Eternal crystals grow here from nothing, as though the Abyss is trying to fill itself.", + durationSeconds: 600, + events: [ + { + effect: { materialId: "eternal_crystal", quantity: 6, type: "dark_material_gain" }, + id: "upper_abyss_growth", + text: "The eternal crystals grow faster than they should. Your thralls harvest full clusters in the time it would take to find a single shard elsewhere — the Abyss produces them as readily as it consumes everything else.", + }, + { + effect: { amount: 6250, type: "blood_loss" }, + id: "upper_abyss_depth", + text: "The depth exerts a pressure that has nothing to do with altitude. Blood rises toward wounds rather than away from them, drawn outward by whatever the Abyss has instead of gravity.", + }, + ], + id: "upper_abyss", + name: "The Upper Abyss", + possibleMaterials: [ + { materialId: "eternal_crystal", maxQuantity: 11, minQuantity: 5, weight: 5 }, + { materialId: "primordial_ash", maxQuantity: 9, minQuantity: 4, weight: 4 }, + { materialId: "void_essence", maxQuantity: 7, minQuantity: 3, weight: 3 }, + ], + zoneId: "vampire_eternal_abyss", + }, + { + description: "The deep Abyss — where void essence collects in pools that have no floor and emit no light. The primordial ash here is so thick it is almost solid. Something enormous moves below.", + durationSeconds: 900, + events: [ + { + effect: { amount: 50000, type: "blood_gain" }, + id: "deep_abyss_pool", + text: "The void essence pools carry concentrated blood from every age — primordial, ancient, recent, all compressed together into something that predates categories. Your thralls fill every vessel with trembling hands.", + }, + { + effect: { fraction: 0.09, type: "thrall_loss" }, + id: "deep_abyss_movement", + text: "The thing below is not hostile. It is simply large, and when it moves, the displacement is enough. Your thralls are scattered. Most find their way back. The rest become part of the deep.", + }, + ], + id: "deep_abyss", + name: "The Deep Abyss", + possibleMaterials: [ + { materialId: "void_essence", maxQuantity: 13, minQuantity: 6, weight: 5 }, + { materialId: "eternal_crystal", maxQuantity: 11, minQuantity: 5, weight: 4 }, + { materialId: "primordial_ash", maxQuantity: 11, minQuantity: 5, weight: 3 }, + ], + zoneId: "vampire_eternal_abyss", + }, + { + description: "The absolute bottom of the Eternal Abyss — or as close to it as anything has ever reached and returned from. Here, void essence and primordial ash and eternal crystal exist in equal measure, in a silence that predates sound.", + durationSeconds: 1200, + events: [ + { + effect: { amount: 100000, type: "blood_gain" }, + id: "abyss_floor_primordial", + text: "The Abyss floor holds the first blood — the blood that was here before anything else was, compressed by eternity into something that makes every other harvest feel like a prelude. Your thralls collect it in silence, in awe, in haste.", + }, + { + effect: { amount: 25000, type: "blood_loss" }, + id: "abyss_floor_price", + text: "The primordial blood exacts a price for being taken. Not from malice — it simply has gravity that everything else lacks. What your thralls carry out, it calls back a portion of. You consider this acceptable. You are not entirely sure you had a choice.", + }, + ], + id: "abyss_floor", + name: "The Abyss Floor", + possibleMaterials: [ + { materialId: "primordial_ash", maxQuantity: 15, minQuantity: 7, weight: 5 }, + { materialId: "void_essence", maxQuantity: 14, minQuantity: 6, weight: 4 }, + { materialId: "eternal_crystal", maxQuantity: 13, minQuantity: 6, weight: 3 }, + ], + zoneId: "vampire_eternal_abyss", + }, +]; diff --git a/apps/api/src/routes/debug.ts b/apps/api/src/routes/debug.ts index 9011b5a..61e63b4 100644 --- a/apps/api/src/routes/debug.ts +++ b/apps/api/src/routes/debug.ts @@ -1280,8 +1280,8 @@ debugRouter.post("/grant-apotheosis", async(context) => { return context.json({ error: "No save found" }, 404); } - /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- Prisma returns JsonValue; cast to GameState */ - const state = record.state as GameState; + /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- Prisma returns JsonValue; double-cast required */ + const state = record.state as unknown as GameState; const updatedState: GameState = (state.apotheosis?.count ?? 0) >= 1 diff --git a/vampire-explorations.md b/vampire-explorations.md new file mode 100644 index 0000000..4f4b19e --- /dev/null +++ b/vampire-explorations.md @@ -0,0 +1,58 @@ +# Vampire Explorations — Progress Tracker + +Tracking file for `vampireExplorations.ts` (72 areas, 4 per zone, 18 zones). +Working in chunks of 3 zones (12 areas) to keep sessions manageable. + +--- + +## Zone ID Reference + +| # | Zone Name | Zone ID | +|---|-----------------------|----------------------------------| +| 1 | Haunted Catacombs | `vampire_haunted_catacombs` | +| 2 | Blood Mire | `vampire_blood_mire` | +| 3 | Obsidian Keep | `vampire_obsidian_keep` | +| 4 | Crimson Citadel | `vampire_crimson_citadel` | +| 5 | Shadow Court | `vampire_shadow_court` | +| 6 | Plague Ossuary | `vampire_plague_ossuary` | +| 7 | Ashen Wastes | `vampire_ashen_wastes` | +| 8 | The Iron Gaol | `vampire_iron_gaol` | +| 9 | Veilborn Hollow | `vampire_veilborn_hollow` | +| 10 | Moonless Moor | `vampire_moonless_moor` | +| 11 | The Sunken Crypt | `vampire_sunken_crypt` | +| 12 | Desecrated Sanctum | `vampire_desecrated_sanctum` | +| 13 | Carrion Peaks | `vampire_carrion_peaks` | +| 14 | The Bloodspire | `vampire_bloodspire` | +| 15 | Shroud of Eternity | `vampire_shroud_of_eternity` | +| 16 | The Abyssal Vault | `vampire_abyssal_vault` | +| 17 | Court of Whispers | `vampire_court_of_whispers` | +| 18 | The Eternal Abyss | `vampire_eternal_abyss` | + +--- + +## Chunk Progress + +| Chunk | Zones | Areas | Status | +|-------|---------|----------|---------------------| +| A | 1–3 | 1–12 | ✅ Complete (2026-04-15) | +| B | 4–6 | 13–24 | ✅ Complete (2026-04-15) | +| C | 7–9 | 25–36 | ✅ Complete (2026-04-15) | +| D | 10–12 | 37–48 | ✅ Complete (2026-04-15) | +| E | 13–15 | 49–60 | ✅ Complete (2026-04-15) | +| F | 16–18 | 61–72 | ✅ Complete (2026-04-15) | + +Once all 6 chunks are complete, `vampireExplorations.ts` is done and Chunk 2 of vampire.md can be marked complete. + +--- + +## Session Log + +| Date | Work Done | +|------------|-----------| +| 2026-04-15 | Created this tracker. Ready to begin Chunk A. | +| 2026-04-15 | Chunk A complete. Zones 1–3, areas 1–12 written. Build passes clean. | +| 2026-04-15 | Chunk B complete. Zones 4–6, areas 13–24 written. Build passes clean. | +| 2026-04-15 | Chunk C complete. Zones 7–9, areas 25–36 written. Build passes clean. | +| 2026-04-15 | Chunk D complete. Zones 10–12, areas 37–48 written. Build passes clean. | +| 2026-04-15 | Chunk E complete. Zones 13–15, areas 49–60 written. Build passes clean. | +| 2026-04-15 | Chunk F complete. Zones 16–18, areas 61–72 written. Build passes clean. ALL 72 AREAS DONE! | diff --git a/vampire.md b/vampire.md index a2d3fc2..23dbcfa 100644 --- a/vampire.md +++ b/vampire.md @@ -139,7 +139,7 @@ Build: ✅ `pnpm --filter @elysium/types build` passes clean. --- ### Chunk 2 — Data -**Status:** ⬜ Not started +**Status:** ✅ Complete (2026-04-15) Files to create in `apps/api/src/data/`: - [ ] `vampireZones.ts` (18 zones) @@ -153,7 +153,7 @@ Files to create in `apps/api/src/data/`: - [ ] `vampireAwakeningUpgrades.ts` (15 upgrades) - [ ] `vampireMaterials.ts` (54 materials) - [ ] `vampireCrafting.ts` (36 recipes) -- [ ] `vampireExplorations.ts` (72 areas, 4 per zone) +- [x] `vampireExplorations.ts` (72 areas, 4 per zone) - [ ] `vampireAchievements.ts` (40 achievements) --- @@ -252,3 +252,4 @@ File to update: `apps/web/src/components/game/aboutPanel.tsx` |------------|-----------| | 2026-04-14 | Created this file. Audit confirmed all Goddess chunks complete. Beginning Vampire Mode. | | 2026-04-14 | Chunk 1 complete. 12 type files created, Resource + GameState + index.ts updated. Build passes clean. | +| 2026-04-15 | Chunk 2 complete. All 13 data files created. vampireExplorations.ts written in 6 sub-chunks (72 areas). Build passes clean. |