feat: add exploration and crafting systems

Adds two new game systems: Exploration (scouts collect materials from
timed area runs) and Crafting (combine materials into permanent
multipliers). Includes 72 exploration areas, 54 materials, 36 recipes,
and 108 new Codex lore entries. Removes unused characterName requirement
from prestige/transcendence/apotheosis reset flows.
This commit is contained in:
2026-03-07 04:14:04 -08:00
committed by Naomi Carrigan
parent 2aa6362ad6
commit 6ddf8e0b43
35 changed files with 4722 additions and 94 deletions
+3 -13
View File
@@ -41,7 +41,6 @@ const CATEGORY_ORDER: PrestigeUpgradeCategory[] = [
export const PrestigePanel = (): React.JSX.Element => {
const { state, reload, formatNumber, buyPrestigeUpgrade, toggleAutoPrestige } = useGame();
const [characterName, setCharacterName] = useState("");
const [isPending, setIsPending] = useState(false);
const [result, setResult] = useState<{ runestones: number; count: number; milestoneRunestones: number } | null>(null);
const [prestigeError, setPrestigeError] = useState<string | null>(null);
@@ -61,11 +60,10 @@ export const PrestigePanel = (): React.JSX.Element => {
const nextMultiplier = calculateProductionMultiplier(prestigeData.count + 1);
const handlePrestige = async (): Promise<void> => {
if (!characterName.trim()) return;
setIsPending(true);
setPrestigeError(null);
try {
const data = await prestige({ characterName: characterName.trim() });
const data = await prestige({});
setResult({ runestones: data.runestones, count: data.newPrestigeCount, milestoneRunestones: data.milestoneRunestones });
await reload();
} catch (err) {
@@ -156,18 +154,10 @@ export const PrestigePanel = (): React.JSX.Element => {
{isEligible ? (
<div className="prestige-form">
<p>You are ready to prestige! Choose your new character name:</p>
<input
disabled={isPending}
maxLength={32}
onChange={(e) => { setCharacterName(e.target.value); }}
placeholder="Character name..."
type="text"
value={characterName}
/>
<p>You are ready to prestige!</p>
<button
className="prestige-button"
disabled={isPending || !characterName.trim()}
disabled={isPending}
onClick={() => { void handlePrestige(); }}
type="button"
>