From 9548b460f287d4aeefc5437d25f781991b7575ca Mon Sep 17 00:00:00 2001 From: Hikari Date: Tue, 14 Apr 2026 18:42:40 -0700 Subject: [PATCH] =?UTF-8?q?feat:=20vampire=20expansion=20chunk=201=20?= =?UTF-8?q?=E2=80=94=20type=20definitions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/types/src/index.ts | 59 ++++ packages/types/src/interfaces/gameState.ts | 6 + packages/types/src/interfaces/resource.ts | 7 + .../src/interfaces/vampireAchievement.ts | 45 ++++ .../types/src/interfaces/vampireAwakening.ts | 79 ++++++ packages/types/src/interfaces/vampireBoss.ts | 69 +++++ .../types/src/interfaces/vampireEquipment.ts | 64 +++++ .../src/interfaces/vampireEquipmentSet.ts | 68 +++++ .../src/interfaces/vampireExploration.ts | 123 +++++++++ packages/types/src/interfaces/vampireQuest.ts | 71 +++++ .../types/src/interfaces/vampireSiring.ts | 75 ++++++ packages/types/src/interfaces/vampireState.ts | 82 ++++++ .../types/src/interfaces/vampireThrall.ts | 46 ++++ .../types/src/interfaces/vampireUpgrade.ts | 37 +++ packages/types/src/interfaces/vampireZone.ts | 28 ++ vampire.md | 254 ++++++++++++++++++ 16 files changed, 1113 insertions(+) create mode 100644 packages/types/src/interfaces/vampireAchievement.ts create mode 100644 packages/types/src/interfaces/vampireAwakening.ts create mode 100644 packages/types/src/interfaces/vampireBoss.ts create mode 100644 packages/types/src/interfaces/vampireEquipment.ts create mode 100644 packages/types/src/interfaces/vampireEquipmentSet.ts create mode 100644 packages/types/src/interfaces/vampireExploration.ts create mode 100644 packages/types/src/interfaces/vampireQuest.ts create mode 100644 packages/types/src/interfaces/vampireSiring.ts create mode 100644 packages/types/src/interfaces/vampireState.ts create mode 100644 packages/types/src/interfaces/vampireThrall.ts create mode 100644 packages/types/src/interfaces/vampireUpgrade.ts create mode 100644 packages/types/src/interfaces/vampireZone.ts create mode 100644 vampire.md diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index 6bcf8e6..32b68de 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -176,6 +176,65 @@ export type { GoddessZone, GoddessZoneStatus, } from "./interfaces/goddessZone.js"; +export type { + AwakeningData, + AwakeningUpgrade, + AwakeningUpgradeCategory, +} from "./interfaces/vampireAwakening.js"; +export type { + VampireAchievement, + VampireAchievementCondition, + VampireAchievementConditionType, + VampireAchievementReward, +} from "./interfaces/vampireAchievement.js"; +export type { + VampireBoss, + VampireBossStatus, +} from "./interfaces/vampireBoss.js"; +export type { + VampireEquipment, + VampireEquipmentBonus, + VampireEquipmentRarity, + VampireEquipmentType, +} from "./interfaces/vampireEquipment.js"; +export type { + VampireEquipmentSet, + VampireEquipmentSetBonus, +} from "./interfaces/vampireEquipmentSet.js"; +export { computeVampireSetBonuses } from "./interfaces/vampireEquipmentSet.js"; +export type { + VampireExplorationArea, + VampireExplorationAreaState, + VampireExplorationEvent, + VampireExplorationEventEffect, + VampireExplorationEventEffectType, + VampireExplorationMaterialDrop, + VampireExplorationState, +} from "./interfaces/vampireExploration.js"; +export type { + VampireQuest, + VampireQuestReward, + VampireQuestRewardType, + VampireQuestStatus, +} from "./interfaces/vampireQuest.js"; +export type { + SiringData, + SiringUpgrade, + SiringUpgradeCategory, +} from "./interfaces/vampireSiring.js"; +export type { VampireState } from "./interfaces/vampireState.js"; +export type { + VampireThrall, + VampireThrallClass, +} from "./interfaces/vampireThrall.js"; +export type { + VampireUpgrade, + VampireUpgradeTarget, +} from "./interfaces/vampireUpgrade.js"; +export type { + VampireZone, + VampireZoneStatus, +} from "./interfaces/vampireZone.js"; export type { Player } from "./interfaces/player.js"; export type { PrestigeData } from "./interfaces/prestige.js"; export type { diff --git a/packages/types/src/interfaces/gameState.ts b/packages/types/src/interfaces/gameState.ts index 69af434..f337092 100644 --- a/packages/types/src/interfaces/gameState.ts +++ b/packages/types/src/interfaces/gameState.ts @@ -14,6 +14,7 @@ import type { DailyChallengeState } from "./dailyChallenge.js"; import type { Equipment } from "./equipment.js"; import type { ExplorationState } from "./exploration.js"; import type { GoddessState } from "./goddessState.js"; +import type { VampireState } from "./vampireState.js"; import type { Player } from "./player.js"; import type { PrestigeData } from "./prestige.js"; import type { Quest } from "./quest.js"; @@ -100,6 +101,11 @@ interface GameState { */ goddess?: GoddessState; + /** + * Vampire expansion state — optional for backwards compatibility with pre-vampire saves. + */ + vampire?: VampireState; + /** * Schema version — used to detect saves from older game versions. */ diff --git a/packages/types/src/interfaces/resource.ts b/packages/types/src/interfaces/resource.ts index 068eb8c..6d70a48 100644 --- a/packages/types/src/interfaces/resource.ts +++ b/packages/types/src/interfaces/resource.ts @@ -17,6 +17,13 @@ interface Resource { prayers?: number; divinity?: number; stardust?: number; + + /** + * Vampire expansion currencies — optional for backwards compatibility with pre-vampire saves. + */ + blood?: number; + ichor?: number; + soulShards?: number; } export type { Resource }; diff --git a/packages/types/src/interfaces/vampireAchievement.ts b/packages/types/src/interfaces/vampireAchievement.ts new file mode 100644 index 0000000..90d9957 --- /dev/null +++ b/packages/types/src/interfaces/vampireAchievement.ts @@ -0,0 +1,45 @@ +/** + * @file Vampire expansion Achievement types for the Elysium game. + * @copyright nhcarrigan + * @license Naomi's Public License + * @author Naomi Carrigan + */ + +type VampireAchievementConditionType = + | "totalBloodEarned" + | "vampireBossesDefeated" + | "vampireQuestsCompleted" + | "thrallTotal" + | "siringCount" + | "vampireEquipmentOwned"; + +interface VampireAchievementCondition { + type: VampireAchievementConditionType; + amount: number; +} + +interface VampireAchievementReward { + ichor?: number; + soulShards?: number; +} + +interface VampireAchievement { + id: string; + name: string; + description: string; + icon: string; + condition: VampireAchievementCondition; + reward?: VampireAchievementReward; + + /** + * Unix timestamp when unlocked, null if not yet unlocked. + */ + unlockedAt: number | null; +} + +export type { + VampireAchievement, + VampireAchievementCondition, + VampireAchievementConditionType, + VampireAchievementReward, +}; diff --git a/packages/types/src/interfaces/vampireAwakening.ts b/packages/types/src/interfaces/vampireAwakening.ts new file mode 100644 index 0000000..59b40c4 --- /dev/null +++ b/packages/types/src/interfaces/vampireAwakening.ts @@ -0,0 +1,79 @@ +/** + * @file Vampire expansion Awakening (transcendence) types for the Elysium game. + * @copyright nhcarrigan + * @license Naomi's Public License + * @author Naomi Carrigan + */ + +type AwakeningUpgradeCategory = + | "blood" + | "combat" + | "siring_threshold" + | "siring_ichor" + | "soulshards_meta"; + +interface AwakeningUpgrade { + id: string; + name: string; + description: string; + category: AwakeningUpgradeCategory; + + /** + * Soul Shards cost to purchase. + */ + cost: number; + + /** + * Multiplicative effect of this upgrade. + */ + multiplier: number; +} + +interface AwakeningData { + + /** + * Number of times the player has achieved The Awakening. + */ + count: number; + + /** + * Soul Shards accumulated across all awakenings. + */ + soulShards: number; + + /** + * IDs of soul shard upgrades purchased. + */ + purchasedUpgradeIds: Array; + + /** + * Pre-computed: multiplier applied to all passive blood income. + */ + soulShardsBloodMultiplier: number; + + /** + * Pre-computed: multiplier applied to thrall DPS in vampire boss fights. + */ + soulShardsCombatMultiplier: number; + + /** + * Pre-computed: multiplier applied to the siring blood threshold (< 1 lowers requirement). + */ + soulShardsSiringThresholdMultiplier: number; + + /** + * Pre-computed: multiplier applied to ichor earned per siring. + */ + soulShardsSiringIchorMultiplier: number; + + /** + * Pre-computed: multiplier applied to soul shards yield on future awakenings. + */ + soulShardsMetaMultiplier: number; +} + +export type { + AwakeningData, + AwakeningUpgrade, + AwakeningUpgradeCategory, +}; diff --git a/packages/types/src/interfaces/vampireBoss.ts b/packages/types/src/interfaces/vampireBoss.ts new file mode 100644 index 0000000..a120e79 --- /dev/null +++ b/packages/types/src/interfaces/vampireBoss.ts @@ -0,0 +1,69 @@ +/** + * @file Vampire expansion Boss types for the Elysium game. + * @copyright nhcarrigan + * @license Naomi's Public License + * @author Naomi Carrigan + */ + +type VampireBossStatus = "locked" | "available" | "in_progress" | "defeated"; + +interface VampireBoss { + id: string; + name: string; + description: string; + status: VampireBossStatus; + maxHp: number; + currentHp: number; + + /** + * Damage dealt to thralls per second whilst the fight is active. + */ + damagePerSecond: number; + + /** + * Blood reward on defeat. + */ + bloodReward: number; + + /** + * Ichor reward on defeat. + */ + ichorReward: number; + + /** + * Soul Shards reward on defeat. + */ + soulShardsReward: number; + + /** + * IDs of vampire upgrades unlocked on defeat. + */ + upgradeRewards: Array; + + /** + * IDs of vampire equipment items granted on defeat. + */ + equipmentRewards: Array; + + /** + * Minimum siring level required to access this boss. + */ + siringRequirement: number; + + /** + * Vampire zone this boss belongs to. + */ + zoneId: string; + + /** + * One-time ichor bounty awarded on first-ever defeat. + */ + bountyIchor: number; + + /** + * Whether the first-kill ichor bounty has already been claimed. + */ + bountyIchorClaimed?: boolean; +} + +export type { VampireBoss, VampireBossStatus }; diff --git a/packages/types/src/interfaces/vampireEquipment.ts b/packages/types/src/interfaces/vampireEquipment.ts new file mode 100644 index 0000000..60071db --- /dev/null +++ b/packages/types/src/interfaces/vampireEquipment.ts @@ -0,0 +1,64 @@ +/** + * @file Vampire expansion Equipment types for the Elysium game. + * @copyright nhcarrigan + * @license Naomi's Public License + * @author Naomi Carrigan + */ + +type VampireEquipmentType = "fang" | "shroud" | "talisman"; + +type VampireEquipmentRarity = "common" | "rare" | "epic" | "legendary"; + +interface VampireEquipmentBonus { + + /** + * Multiplier applied to all blood/s income (e.g. 1.1 = +10%). + */ + bloodMultiplier?: number; + + /** + * Multiplier applied to all thrall combat power (e.g. 1.25 = +25%). + */ + combatMultiplier?: number; + + /** + * Multiplier applied to ichor earned per siring (e.g. 1.5 = +50%). + */ + ichorMultiplier?: number; +} + +interface VampireEquipment { + id: string; + name: string; + description: string; + type: VampireEquipmentType; + rarity: VampireEquipmentRarity; + bonus: VampireEquipmentBonus; + + /** + * Whether the player has acquired this item. + */ + owned: boolean; + + /** + * Whether this item is currently equipped (only one per type can be equipped). + */ + equipped: boolean; + + /** + * If set, this item can be purchased directly rather than obtained via vampire boss drops. + */ + cost?: { blood: number; ichor: number; soulShards: number }; + + /** + * Vampire equipment set this item belongs to, if any. + */ + setId?: string; +} + +export type { + VampireEquipment, + VampireEquipmentBonus, + VampireEquipmentRarity, + VampireEquipmentType, +}; diff --git a/packages/types/src/interfaces/vampireEquipmentSet.ts b/packages/types/src/interfaces/vampireEquipmentSet.ts new file mode 100644 index 0000000..5b2e821 --- /dev/null +++ b/packages/types/src/interfaces/vampireEquipmentSet.ts @@ -0,0 +1,68 @@ +/** + * @file Vampire expansion Equipment Set types for the Elysium game. + * @copyright nhcarrigan + * @license Naomi's Public License + * @author Naomi Carrigan + */ + +interface VampireEquipmentSetBonus { + bloodMultiplier?: number; + combatMultiplier?: number; + ichorMultiplier?: number; +} + +interface VampireEquipmentSet { + id: string; + name: string; + description: string; + + /** + * Vampire equipment IDs that make up this set. + */ + pieces: Array; + bonuses: { + // eslint-disable-next-line @typescript-eslint/naming-convention -- numeric keys + 2: VampireEquipmentSetBonus; + // eslint-disable-next-line @typescript-eslint/naming-convention -- numeric keys + 3: VampireEquipmentSetBonus; + }; +} + +/** + * Given a list of equipped vampire item IDs and a set catalogue, returns the + * combined multiplicative bonuses granted by all active set bonuses. + * @param equippedItemIds - The IDs of vampire items currently equipped. + * @param sets - The full catalogue of vampire equipment sets to evaluate against. + * @returns The combined blood, combat, and ichor multipliers from active set bonuses. + */ +const computeVampireSetBonuses = ( + equippedItemIds: Array, + sets: Array, +): { + bloodMultiplier: number; + combatMultiplier: number; + ichorMultiplier: number; +} => { + let bloodMultiplier = 1; + let combatMultiplier = 1; + let ichorMultiplier = 1; + + for (const set of sets) { + const count = set.pieces.filter((id) => { + return equippedItemIds.includes(id); + }).length; + for (const threshold of [ 2, 3 ] as const) { + if (count >= threshold) { + const bonus = set.bonuses[threshold]; + bloodMultiplier = bloodMultiplier * (bonus.bloodMultiplier ?? 1); + combatMultiplier = combatMultiplier * (bonus.combatMultiplier ?? 1); + ichorMultiplier = ichorMultiplier * (bonus.ichorMultiplier ?? 1); + } + } + } + + return { bloodMultiplier, combatMultiplier, ichorMultiplier }; +}; + +export type { VampireEquipmentSet, VampireEquipmentSetBonus }; +export { computeVampireSetBonuses }; diff --git a/packages/types/src/interfaces/vampireExploration.ts b/packages/types/src/interfaces/vampireExploration.ts new file mode 100644 index 0000000..b9055ef --- /dev/null +++ b/packages/types/src/interfaces/vampireExploration.ts @@ -0,0 +1,123 @@ +/** + * @file Vampire expansion Exploration types for the Elysium game. + * @copyright nhcarrigan + * @license Naomi's Public License + * @author Naomi Carrigan + */ + +type VampireExplorationEventEffectType = + | "blood_gain" + | "blood_loss" + | "ichor_gain" + | "dark_material_gain" + | "thrall_loss"; + +interface VampireExplorationEventEffect { + type: VampireExplorationEventEffectType; + + /** + * Blood amount for blood_gain / blood_loss. + */ + amount?: number; + + /** + * Dark material ID for dark_material_gain. + */ + materialId?: string; + + /** + * Quantity for dark_material_gain. + */ + quantity?: number; + + /** + * Fraction (0–1) of total thralls lost for thrall_loss. + */ + fraction?: number; +} + +interface VampireExplorationEvent { + id: string; + text: string; + effect: VampireExplorationEventEffect; +} + +interface VampireExplorationMaterialDrop { + materialId: string; + minQuantity: number; + maxQuantity: number; + + /** + * Relative probability weight — higher = more likely. + */ + weight: number; +} + +interface VampireExplorationArea { + id: string; + name: string; + description: string; + zoneId: string; + durationSeconds: number; + possibleMaterials: Array; + events: Array; +} + +interface VampireExplorationAreaState { + id: string; + status: "locked" | "available" | "in_progress" | "completed"; + + /** + * Unix timestamp when exploration started (set when status becomes in_progress). + */ + startedAt?: number; + + /** + * Unix timestamp when the exploration will complete. + */ + endsAt?: number; + + /** + * True after the first successful collect — used for codex unlock detection. + */ + completedOnce?: boolean; +} + +interface VampireExplorationState { + areas: Array; + + /** + * Current dark material inventory. + */ + materials: Array<{ materialId: string; quantity: number }>; + + /** + * IDs of vampire crafting recipes that have been crafted (resets on siring). + */ + craftedRecipeIds: Array; + + /** + * Pre-computed blood income multiplier from all crafted vampire recipes. + */ + craftedBloodMultiplier: number; + + /** + * Pre-computed ichor income multiplier from all crafted vampire recipes. + */ + craftedIchorMultiplier: number; + + /** + * Pre-computed combat power multiplier from all crafted vampire recipes. + */ + craftedCombatMultiplier: number; +} + +export type { + VampireExplorationArea, + VampireExplorationAreaState, + VampireExplorationEvent, + VampireExplorationEventEffect, + VampireExplorationEventEffectType, + VampireExplorationMaterialDrop, + VampireExplorationState, +}; diff --git a/packages/types/src/interfaces/vampireQuest.ts b/packages/types/src/interfaces/vampireQuest.ts new file mode 100644 index 0000000..861061f --- /dev/null +++ b/packages/types/src/interfaces/vampireQuest.ts @@ -0,0 +1,71 @@ +/** + * @file Vampire expansion Quest types for the Elysium game. + * @copyright nhcarrigan + * @license Naomi's Public License + * @author Naomi Carrigan + */ + +type VampireQuestStatus = "locked" | "available" | "active" | "completed"; + +type VampireQuestRewardType = + | "blood" + | "ichor" + | "soulShards" + | "upgrade" + | "thrall" + | "equipment"; + +interface VampireQuestReward { + type: VampireQuestRewardType; + amount?: number; + + /** + * ID of the vampire upgrade or thrall class to unlock (if applicable). + */ + targetId?: string; +} + +interface VampireQuest { + id: string; + name: string; + description: string; + status: VampireQuestStatus; + + /** + * Unix timestamp when quest was started (if active). + */ + startedAt?: number; + + /** + * Duration in seconds. + */ + durationSeconds: number; + rewards: Array; + + /** + * IDs of vampire quests that must be completed before this one unlocks. + */ + prerequisiteIds: Array; + + /** + * Vampire zone this quest belongs to. + */ + zoneId: string; + + /** + * Minimum thrall combat power required to start this quest. + */ + combatPowerRequired?: number; + + /** + * Unix timestamp of the most recent failed attempt (if any). + */ + lastFailedAt?: number; +} + +export type { + VampireQuest, + VampireQuestReward, + VampireQuestRewardType, + VampireQuestStatus, +}; diff --git a/packages/types/src/interfaces/vampireSiring.ts b/packages/types/src/interfaces/vampireSiring.ts new file mode 100644 index 0000000..376d923 --- /dev/null +++ b/packages/types/src/interfaces/vampireSiring.ts @@ -0,0 +1,75 @@ +/** + * @file Vampire expansion Siring (prestige) types for the Elysium game. + * @copyright nhcarrigan + * @license Naomi's Public License + * @author Naomi Carrigan + */ + +type SiringUpgradeCategory = + | "blood" + | "thralls" + | "combat" + | "ichor" + | "utility"; + +interface SiringUpgrade { + id: string; + name: string; + description: string; + category: SiringUpgradeCategory; + ichorCost: number; + + /** + * Multiplier applied when this upgrade is purchased. + */ + multiplier: number; +} + +interface SiringData { + + /** + * Number of times the player has sired (vampire prestige). + */ + count: number; + + /** + * Ichor carried over between sirings. + */ + ichor: number; + + /** + * Multiplier applied to all blood/s production (based on siring count). + */ + productionMultiplier: number; + + /** + * IDs of siring upgrades purchased with ichor. + */ + purchasedUpgradeIds: Array; + + /** + * Unix timestamp of last siring. + */ + lastSiredAt?: number; + + /** + * Pre-computed multiplier from "blood" ichor upgrades. + */ + ichorBloodMultiplier?: number; + + /** + * Pre-computed multiplier from "thralls" ichor upgrades. + */ + ichorThrallsMultiplier?: number; + + /** + * Pre-computed multiplier from "combat" ichor upgrades. + */ + ichorCombatMultiplier?: number; +} + +export type { + SiringData, + SiringUpgrade, + SiringUpgradeCategory, +}; diff --git a/packages/types/src/interfaces/vampireState.ts b/packages/types/src/interfaces/vampireState.ts new file mode 100644 index 0000000..95a26f8 --- /dev/null +++ b/packages/types/src/interfaces/vampireState.ts @@ -0,0 +1,82 @@ +/** + * @file Vampire expansion state types for the Elysium game. + * @copyright nhcarrigan + * @license Naomi's Public License + * @author Naomi Carrigan + */ +import type { AwakeningData } from "./vampireAwakening.js"; +import type { VampireAchievement } from "./vampireAchievement.js"; +import type { VampireBoss } from "./vampireBoss.js"; +import type { VampireEquipment } from "./vampireEquipment.js"; +import type { VampireExplorationState } from "./vampireExploration.js"; +import type { VampireQuest } from "./vampireQuest.js"; +import type { SiringData } from "./vampireSiring.js"; +import type { VampireThrall } from "./vampireThrall.js"; +import type { VampireUpgrade } from "./vampireUpgrade.js"; +import type { VampireZone } from "./vampireZone.js"; + +interface VampireState { + zones: Array; + bosses: Array; + quests: Array; + thralls: Array; + equipment: Array; + upgrades: Array; + achievements: Array; + siring: SiringData; + awakening: AwakeningData; + exploration: VampireExplorationState; + + /** + * Total blood earned in the current siring run (resets on siring). + */ + totalBloodEarned: number; + + /** + * Total blood earned across all time (never resets — used for achievements and unlock thresholds). + */ + lifetimeBloodEarned: number; + + /** + * Total vampire bosses defeated across all time. + */ + lifetimeBossesDefeated: number; + + /** + * Total vampire quests completed across all time. + */ + lifetimeQuestsCompleted: number; + + /** + * Click power for the vampire realm (blood per hunt, before upgrades). + */ + baseClickPower: number; + + /** + * Unix timestamp of the last vampire-side client tick. + */ + lastTickAt: number; + + /** + * When true, the tick engine automatically starts the highest-zone available vampire quest. + */ + autoQuest?: boolean; + + /** + * When true, the tick engine automatically challenges the highest available vampire boss. + */ + autoBoss?: boolean; + + /** + * When true, the tick engine automatically purchases the highest-tier affordable thrall. + */ + autoThrall?: boolean; + + /** + * Count of Eternal Sovereignty achievements (vampire apotheosis equivalent). + * Goddess Mode unlocks once this reaches 1. + */ + eternalSovereignty: { count: number }; +} + +export type { VampireState }; diff --git a/packages/types/src/interfaces/vampireThrall.ts b/packages/types/src/interfaces/vampireThrall.ts new file mode 100644 index 0000000..265339e --- /dev/null +++ b/packages/types/src/interfaces/vampireThrall.ts @@ -0,0 +1,46 @@ +/** + * @file Vampire expansion Thrall types for the Elysium game. + * @copyright nhcarrigan + * @license Naomi's Public License + * @author Naomi Carrigan + */ + +type VampireThrallClass = + | "fledgling" + | "revenant" + | "shade" + | "bloodbound" + | "wraith" + | "ancient"; + +interface VampireThrall { + id: string; + name: string; + class: VampireThrallClass; + level: number; + + /** + * Base cost for the first purchase of this tier (scales by 1.15× per count). + * Paid in blood. + */ + baseCost: number; + + /** + * Base blood generated per second. + */ + bloodPerSecond: number; + + /** + * Base ichor generated per second. + */ + ichorPerSecond: number; + + /** + * Combat power per unit — used in vampire boss battle simulation. + */ + combatPower: number; + count: number; + unlocked: boolean; +} + +export type { VampireThrall, VampireThrallClass }; diff --git a/packages/types/src/interfaces/vampireUpgrade.ts b/packages/types/src/interfaces/vampireUpgrade.ts new file mode 100644 index 0000000..a6fdee3 --- /dev/null +++ b/packages/types/src/interfaces/vampireUpgrade.ts @@ -0,0 +1,37 @@ +/** + * @file Vampire expansion Upgrade types for the Elysium game. + * @copyright nhcarrigan + * @license Naomi's Public License + * @author Naomi Carrigan + */ + +type VampireUpgradeTarget = + | "blood" + | "thrall" + | "global" + | "siring" + | "boss"; + +interface VampireUpgrade { + id: string; + name: string; + description: string; + target: VampireUpgradeTarget; + + /** + * ID of the thrall class this applies to (if target is "thrall"). + */ + thrallId?: string; + + /** + * Multiplier applied to the target's output. + */ + multiplier: number; + costBlood: number; + costIchor: number; + costSoulShards: number; + purchased: boolean; + unlocked: boolean; +} + +export type { VampireUpgrade, VampireUpgradeTarget }; diff --git a/packages/types/src/interfaces/vampireZone.ts b/packages/types/src/interfaces/vampireZone.ts new file mode 100644 index 0000000..431bbd7 --- /dev/null +++ b/packages/types/src/interfaces/vampireZone.ts @@ -0,0 +1,28 @@ +/** + * @file Vampire expansion Zone types for the Elysium game. + * @copyright nhcarrigan + * @license Naomi's Public License + * @author Naomi Carrigan + */ + +type VampireZoneStatus = "locked" | "unlocked"; + +interface VampireZone { + id: string; + name: string; + description: string; + emoji: string; + status: VampireZoneStatus; + + /** + * Vampire boss ID whose defeat is required to unlock this zone (null for the starter zone). + */ + unlockBossId: string | null; + + /** + * Vampire quest ID that must be completed to unlock this zone (null for the starter zone). + */ + unlockQuestId: string | null; +} + +export type { VampireZone, VampireZoneStatus }; diff --git a/vampire.md b/vampire.md new file mode 100644 index 0000000..a2d3fc2 --- /dev/null +++ b/vampire.md @@ -0,0 +1,254 @@ +# Vampire Mode — Implementation Progress + +Tracking file for the Vampire Mode expansion (Issue #131). +Update this file at the start and end of every chunk so we can resume safely after any crash. + +--- + +## Unlock Chain (corrected) + +``` +Mortal → Apotheosis → Vampire Mode → Eternal Sovereignty → Goddess Mode → Deification +``` + +- **Vampire Mode** unlocks at `apotheosis.count >= 1` +- **Goddess Mode** unlocks at `vampire.eternalSovereignty.count >= 1` + +--- + +## Terminology + +| Base Game | Vampire Mode | +|-----------------|--------------------| +| Gold | Blood | +| Essence | Ichor | +| Crystals | Soul Shards | +| Runestones | Bloodstones | +| Echoes | Whispers | +| Click action | Hunt | +| Adventurers | Thralls | +| Prestige | Siring | +| Transcendence | The Awakening | +| Apotheosis | Eternal Sovereignty| + +--- + +## Tuning + +| Setting | Base Game | Vampire Mode | +|------------------------|-----------|---------------------| +| Gold income multiplier | 1× | ~0.3× | +| Boss HP | Standard | Substantially higher| +| Quest failure chance | 10%–40% | 20%–60% | +| Prestige threshold | Standard | Higher | +| Transcendence threshold| Standard | Higher | + +--- + +## Content Scale + +| Content Type | Count | +|---------------------------|-------| +| Zones | 18 | +| Bosses | 72 (~4 per zone) | +| Quests | 90 (~5 per zone) | +| Thrall tiers | 32 | +| Equipment pieces | 53 | +| Equipment sets | 9 | +| Upgrades | 58 | +| Siring upgrades | 25 | +| Awakening upgrades | 15 | +| Achievements | 40 | +| Exploration areas | 72 (4 per zone) | +| Crafting recipes | 36 | +| Materials | 54 | + +--- + +## Colour Palette (`.vampire-mode`) + +| Role | Use | Hex | +|---------|--------------|-----------| +| Primary | Dark blood | `#5C0A1A` | +| Secondary | Rich crimson | `#C41E3A` | + +--- + +## Zone List (18 zones — gothic/vampire theme) + +1. Haunted Catacombs +2. Blood Mire +3. Obsidian Keep +4. Crimson Citadel +5. Shadow Court +6. Plague Ossuary +7. Ashen Wastes +8. The Iron Gaol +9. Veilborn Hollow +10. Moonless Moor +11. The Sunken Crypt +12. Desecrated Sanctum +13. Carrion Peaks +14. The Bloodspire +15. Shroud of Eternity +16. The Abyssal Vault +17. Court of Whispers +18. The Eternal Abyss + +--- + +## Thrall Classes (6 classes for 32 tiers, mirroring disciple pattern) + +| Class | Flavour | +|--------------|-------------------------------------| +| Fledgling | Newly turned, weak but numerous | +| Revenant | Undead soldiers, reliable fighters | +| Shade | Shadow-walkers, passive blood earners| +| Bloodbound | Thralls bound by blood oath | +| Wraith | Semi-corporeal, ichor specialists | +| Ancient | Elder thralls, peak power | + +--- + +## Chunk Progress + +### Chunk 1 — Types +**Status:** ✅ Complete (2026-04-14) + +Files to create in `packages/types/src/interfaces/`: +- [x] `vampireZone.ts` +- [x] `vampireBoss.ts` +- [x] `vampireQuest.ts` +- [x] `vampireThrall.ts` +- [x] `vampireEquipment.ts` +- [x] `vampireEquipmentSet.ts` (includes `computeVampireSetBonuses`) +- [x] `vampireUpgrade.ts` +- [x] `vampireSiring.ts` +- [x] `vampireAwakening.ts` +- [x] `vampireAchievement.ts` +- [x] `vampireExploration.ts` +- [x] `vampireState.ts` (includes `eternalSovereignty` count for goddess unlock gate) + +Files to update: +- [x] `resource.ts` — added `blood?`, `ichor?`, `soulShards?` optional fields +- [x] `gameState.ts` — added `vampire?: VampireState` +- [x] `packages/types/src/index.ts` — all new types exported + +Build: ✅ `pnpm --filter @elysium/types build` passes clean. + +--- + +### Chunk 2 — Data +**Status:** ⬜ Not started + +Files to create in `apps/api/src/data/`: +- [ ] `vampireZones.ts` (18 zones) +- [ ] `vampireBosses.ts` (72 bosses) +- [ ] `vampireQuests.ts` (90 quests) +- [ ] `vampireThralls.ts` (32 tiers across 6 classes) +- [ ] `vampireEquipment.ts` (53 pieces) +- [ ] `vampireEquipmentSets.ts` (9 sets) +- [ ] `vampireUpgrades.ts` (58 upgrades) +- [ ] `vampireSiringUpgrades.ts` (25 upgrades) +- [ ] `vampireAwakeningUpgrades.ts` (15 upgrades) +- [ ] `vampireMaterials.ts` (54 materials) +- [ ] `vampireCrafting.ts` (36 recipes) +- [ ] `vampireExplorations.ts` (72 areas, 4 per zone) +- [ ] `vampireAchievements.ts` (40 achievements) + +--- + +### Chunk 3 — Sync / Sanitize +**Status:** ⬜ Not started + +File to update: `apps/api/src/routes/game.ts` +- [ ] `validateAndSanitize` — inject vampire state defaults for existing saves +- [ ] `syncNewContent` — inject missing vampire fields +- [ ] Unlock Goddess Mode once `vampire.eternalSovereignty.count >= 1` (update goddess lock logic) + +--- + +### Chunk 4 — API Routes +**Status:** ⬜ Not started + +Files to create in `apps/api/src/routes/`: +- [ ] `vampireBoss.ts` — vampire boss fight +- [ ] `siring.ts` — siring (prestige) route +- [ ] `awakening.ts` — awakening (transcendence) route +- [ ] `vampireUpgrade.ts` — upgrade purchase +- [ ] `vampireCraft.ts` — crafting +- [ ] `vampireExplore.ts` — exploration + +File to update: +- [ ] `apps/api/src/index.ts` — register all new routes + +--- + +### Chunk 5 — UI: Resource Bar + Mode/Tab Nav +**Status:** ⬜ Not started + +- [ ] `resourceBar.tsx` — add Blood/Ichor/Soul Shards (greyed pre-apotheosis) +- [ ] `gameLayout.tsx` — fix vampire unlock condition (`apotheosis.count >= 1`) +- [ ] `gameLayout.tsx` — fix goddess unlock condition (`vampire.eternalSovereignty.count >= 1`) +- [ ] `gameLayout.tsx` — add vampire tab array (11 tabs) +- [ ] `gameLayout.tsx` — add `.vampire-mode` body class toggle +- [ ] `gameLayout.tsx` — render vampire panels in the panel conditional chain + +--- + +### Chunk 6 — UI: Vampire Panels +**Status:** ⬜ Not started + +Files to create in `apps/web/src/components/game/`: +- [ ] `vampireZonesPanel.tsx` +- [ ] `vampireBossPanel.tsx` +- [ ] `vampireQuestsPanel.tsx` +- [ ] `thrallsPanel.tsx` +- [ ] `vampireEquipmentPanel.tsx` +- [ ] `vampireUpgradesPanel.tsx` +- [ ] `siringPanel.tsx` +- [ ] `awakeningPanel.tsx` +- [ ] `vampireCraftingPanel.tsx` +- [ ] `vampireExplorationPanel.tsx` +- [ ] `vampireAchievementsPanel.tsx` + +--- + +### Chunk 7 — Tick Engine +**Status:** ⬜ Not started + +File to update: `apps/web/src/engine/tick.ts` +- [ ] Vampire passive income (blood per tick from thralls) +- [ ] Ichor per tick from thralls +- [ ] Quest timers — vampire quest completion and rewards +- [ ] Lock state checks — zone/quest/boss unlock logic +- [ ] Achievement checks — vampire achievement conditions +- [ ] Offline income covers vampire mode + +--- + +### Chunk 8 — CSS Theme +**Status:** ⬜ Not started + +File to update: `apps/web/src/styles.css` +- [ ] `body.vampire-mode` CSS variable overrides (bg, surface, accent, gold, text) +- [ ] 0.3s fade transition on all major layout elements +- [ ] Vampire-specific panel and UI element styles + +--- + +### Chunk 9 — About Page +**Status:** ⬜ Not started + +File to update: `apps/web/src/components/game/aboutPanel.tsx` +- [ ] Add Vampire Mode section to `HOW_TO_PLAY` array +- [ ] Document: mode switching, currencies, zones, bosses, quests, thralls, equipment, upgrades, siring, awakening, crafting, exploration, achievements + +--- + +## Session Log + +| Date | Work Done | +|------------|-----------| +| 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. |