refactor: remove memory slot system and Memories section from PrestigeTab
Build and Publish Mana Loop Docker Image / build-and-publish (push) Successful in 1m26s
Build and Publish Mana Loop Docker Image / build-and-publish (push) Successful in 1m26s
- Remove deepMemory prestige upgrade from constants/prestige.ts - Remove Memory interface from types.ts - Remove memorySlots, memories, addMemory, removeMemory, clearMemories from prestigeStore.ts - Remove deepMemory/memory references from gameLoopActions.ts - Remove MemoriesCard component and its usage from PrestigeTab.tsx - Remove memorySlots display from LoopStatsSection.tsx - Update tests: store-actions-combat-prestige.test.ts, PrestigeTab.test.ts, tick-integration.test.ts The memory slot system was fully wired but had no gameplay mechanic — addMemory() was never called outside tests. This removes dead code across 9 files.
This commit is contained in:
@@ -1,11 +1,13 @@
|
||||
# Circular Dependencies
|
||||
Generated: 2026-05-23T17:29:49.986Z
|
||||
Found: 4 circular chain(s) — these MUST be fixed before modifying involved files.
|
||||
Generated: 2026-05-24T12:34:53.927Z
|
||||
Found: 6 circular chain(s) — these MUST be fixed before modifying involved files.
|
||||
|
||||
1. Processed 132 files (1.4s) (3 warnings)
|
||||
2. 1) stores/gameStore.ts > stores/gameActions.ts
|
||||
3. 2) stores/gameStore.ts > stores/gameLoopActions.ts
|
||||
4. 3) stores/gameStore.ts > stores/tick-pipeline.ts
|
||||
1. Processed 132 files (1.4s) (2 warnings)
|
||||
2. 1) utils/floor-utils.ts > utils/room-utils.ts > utils/enemy-utils.ts
|
||||
3. 2) utils/floor-utils.ts > utils/room-utils.ts
|
||||
4. 3) stores/gameStore.ts > stores/gameActions.ts
|
||||
5. 4) stores/gameStore.ts > stores/gameLoopActions.ts
|
||||
6. 5) stores/gameStore.ts > stores/tick-pipeline.ts
|
||||
|
||||
## How to fix
|
||||
1. Identify which import in the chain can be extracted to a shared types/utils file.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"_meta": {
|
||||
"generated": "2026-05-23T17:29:48.378Z",
|
||||
"generated": "2026-05-24T12:34:52.317Z",
|
||||
"description": "Import dependency graph for src/lib/game. Keys are files, values are arrays of files they import.",
|
||||
"usage": "To find what a file affects, search for its path in the VALUES. To find what a file depends on, look at its KEY entry."
|
||||
},
|
||||
@@ -203,6 +203,7 @@
|
||||
"types/disciplines.ts"
|
||||
],
|
||||
"data/enchantment-effects.ts": [
|
||||
"data/enchantment-types.ts",
|
||||
"data/enchantments/index.ts"
|
||||
],
|
||||
"data/enchantment-types.ts": [
|
||||
@@ -361,7 +362,9 @@
|
||||
"data/golems/types.ts",
|
||||
"data/golems/utils.ts"
|
||||
],
|
||||
"data/golems/types.ts": [],
|
||||
"data/golems/types.ts": [
|
||||
"types.ts"
|
||||
],
|
||||
"data/golems/utils.ts": [
|
||||
"data/golems/golems-data.ts",
|
||||
"data/golems/types.ts"
|
||||
@@ -374,7 +377,7 @@
|
||||
"types.ts"
|
||||
],
|
||||
"data/loot-drops.ts": [
|
||||
"types.ts"
|
||||
"types/game.ts"
|
||||
],
|
||||
"effects.ts": [
|
||||
"data/enchantment-effects.ts",
|
||||
@@ -441,7 +444,8 @@
|
||||
"utils/safe-persist.ts"
|
||||
],
|
||||
"stores/crafting-initial-state.ts": [
|
||||
"crafting-utils.ts"
|
||||
"crafting-utils.ts",
|
||||
"types.ts"
|
||||
],
|
||||
"stores/craftingStore.ts": [
|
||||
"crafting-actions/application-actions.ts",
|
||||
@@ -472,6 +476,7 @@
|
||||
"data/disciplines/enchanter.ts",
|
||||
"data/disciplines/fabricator.ts",
|
||||
"data/disciplines/invoker.ts",
|
||||
"types.ts",
|
||||
"types/disciplines.ts",
|
||||
"utils/discipline-math.ts",
|
||||
"utils/safe-persist.ts"
|
||||
@@ -631,7 +636,8 @@
|
||||
],
|
||||
"utils/floor-utils.ts": [
|
||||
"constants.ts",
|
||||
"data/guardian-encounters.ts"
|
||||
"data/guardian-encounters.ts",
|
||||
"utils/room-utils.ts"
|
||||
],
|
||||
"utils/formatting.ts": [],
|
||||
"utils/index.ts": [
|
||||
|
||||
@@ -28,9 +28,9 @@ describe('Tab barrel export', () => {
|
||||
// ─── Test: Prestige upgrade definitions ────────────────────────────────────────
|
||||
|
||||
describe('Prestige upgrade definitions', () => {
|
||||
it('has exactly 14 prestige upgrades', async () => {
|
||||
it('has exactly 13 prestige upgrades', async () => {
|
||||
const { PRESTIGE_DEF } = await import('@/lib/game/constants/prestige');
|
||||
expect(Object.keys(PRESTIGE_DEF).length).toBe(14);
|
||||
expect(Object.keys(PRESTIGE_DEF).length).toBe(13);
|
||||
});
|
||||
|
||||
it('all upgrades have required fields', async () => {
|
||||
@@ -46,7 +46,7 @@ describe('Prestige upgrade definitions', () => {
|
||||
it('all 14 expected upgrade IDs are present', async () => {
|
||||
const { PRESTIGE_DEF } = await import('@/lib/game/constants/prestige');
|
||||
const expectedIds = [
|
||||
'manaWell', 'manaFlow', 'deepMemory', 'insightAmp', 'spireKey',
|
||||
'manaWell', 'manaFlow', 'insightAmp', 'spireKey',
|
||||
'temporalEcho', 'steadyHand', 'ancientKnowledge', 'elementalAttune',
|
||||
'spellMemory', 'guardianPact', 'quickStart', 'elemStart',
|
||||
'unlockedManaTypeCapacity',
|
||||
|
||||
@@ -56,33 +56,6 @@ function InsightSummary({ insight, totalInsight, loopCount, loopInsight }: {
|
||||
);
|
||||
}
|
||||
|
||||
// ─── Memories Card ────────────────────────────────────────────────────────────
|
||||
|
||||
function MemoriesCard({ memories, memorySlots }: { memories: { skillId: string; level: number; tier: number }[]; memorySlots: number }) {
|
||||
return (
|
||||
<Card className="bg-gray-900/60 border-gray-700">
|
||||
<SectionHeader title="🧠 Memories" />
|
||||
<CardContent className="pt-0">
|
||||
<p className="text-xs text-gray-400 mb-2">
|
||||
Skills carried between loops. Slots: {memories.length}/{memorySlots}
|
||||
</p>
|
||||
{memories.length === 0 ? (
|
||||
<p className="text-xs text-gray-500 italic">No memories stored yet.</p>
|
||||
) : (
|
||||
<div className="space-y-1">
|
||||
{memories.map((m) => (
|
||||
<div key={m.skillId} className="text-xs text-gray-300 flex justify-between">
|
||||
<span>{m.skillId}</span>
|
||||
<span className="text-gray-500">Lv.{m.level} T{m.tier}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
// ─── Pacts Card ───────────────────────────────────────────────────────────────
|
||||
|
||||
function PactsCard({ signedPacts, pactSlots, defeatedGuardians }: {
|
||||
@@ -177,7 +150,7 @@ function ResetLoopSection({ loopInsight, onReset }: { loopInsight: number; onRes
|
||||
<div>
|
||||
<h3 className="text-lg font-semibold text-red-400">Reset Loop</h3>
|
||||
<p className="text-xs text-gray-400 mt-1">
|
||||
End the current loop and gain {fmt(loopInsight)} insight. Your prestige upgrades, memories, and pacts are preserved.
|
||||
End the current loop and gain {fmt(loopInsight)} insight. Your prestige upgrades and pacts are preserved.
|
||||
</p>
|
||||
</div>
|
||||
<AlertDialog>
|
||||
@@ -191,7 +164,7 @@ function ResetLoopSection({ loopInsight, onReset }: { loopInsight: number; onRes
|
||||
<AlertDialogTitle>Reset the Loop?</AlertDialogTitle>
|
||||
<AlertDialogDescription>
|
||||
This will end your current loop and award you <strong className="text-amber-400">{fmt(loopInsight)} insight</strong>.
|
||||
Your prestige upgrades, memories, and pacts will be preserved.
|
||||
Your prestige upgrades and pacts will be preserved.
|
||||
<br /><br />
|
||||
Day, hour, mana, floor progress, and combat state will be reset.
|
||||
</AlertDialogDescription>
|
||||
@@ -221,8 +194,6 @@ export function PrestigeTab() {
|
||||
loopInsight,
|
||||
loopCount,
|
||||
prestigeUpgrades,
|
||||
memorySlots,
|
||||
memories,
|
||||
pactSlots,
|
||||
signedPacts,
|
||||
defeatedGuardians,
|
||||
@@ -233,8 +204,6 @@ export function PrestigeTab() {
|
||||
loopInsight: s.loopInsight,
|
||||
loopCount: s.loopCount,
|
||||
prestigeUpgrades: s.prestigeUpgrades,
|
||||
memorySlots: s.memorySlots,
|
||||
memories: s.memories,
|
||||
pactSlots: s.pactSlots,
|
||||
signedPacts: s.signedPacts,
|
||||
defeatedGuardians: s.defeatedGuardians,
|
||||
@@ -275,10 +244,7 @@ export function PrestigeTab() {
|
||||
loopInsight={loopInsight}
|
||||
/>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<MemoriesCard memories={memories} memorySlots={memorySlots} />
|
||||
<PactsCard signedPacts={signedPacts} pactSlots={pactSlots} defeatedGuardians={defeatedGuardians} />
|
||||
</div>
|
||||
|
||||
<Card className="bg-gray-900/60 border-gray-700">
|
||||
<SectionHeader title="⬆️ Prestige Upgrades" />
|
||||
|
||||
@@ -14,7 +14,6 @@ export function LoopStatsSection() {
|
||||
const maxFloorReached = useCombatStore((s) => s.maxFloorReached);
|
||||
const totalManaGathered = useManaStore((s) => s.totalManaGathered);
|
||||
const loopCount = usePrestigeStore((s) => s.loopCount);
|
||||
const memorySlots = usePrestigeStore((s) => s.memorySlots);
|
||||
|
||||
const spellsLearned = Object.values(spells || {}).filter((s: SpellState) => s.learned).length;
|
||||
|
||||
@@ -46,7 +45,7 @@ export function LoopStatsSection() {
|
||||
</div>
|
||||
</div>
|
||||
<Separator className="bg-[var(--border-subtle)] my-3" />
|
||||
<div className="grid grid-cols-2 md:grid-cols-4 gap-4">
|
||||
<div className="grid grid-cols-2 md:grid-cols-3 gap-4">
|
||||
<div className="p-3 bg-[var(--bg-sunken)]/50 rounded text-center">
|
||||
<div className="text-xl font-bold text-[var(--text-secondary)] game-mono">{spellsLearned}</div>
|
||||
<div className="text-xs" style={{ color: 'var(--text-muted)' }}>Spells Learned</div>
|
||||
@@ -55,10 +54,6 @@ export function LoopStatsSection() {
|
||||
<div className="text-xl font-bold text-[var(--text-secondary)] game-mono">{fmt(totalManaGathered)}</div>
|
||||
<div className="text-xs" style={{ color: 'var(--text-muted)' }}>Total Mana Gathered</div>
|
||||
</div>
|
||||
<div className="p-3 bg-[var(--bg-sunken)]/50 rounded text-center">
|
||||
<div className="text-xl font-bold text-[var(--text-secondary)] game-mono">{memorySlots}</div>
|
||||
<div className="text-xs" style={{ color: 'var(--text-muted)' }}>Memory Slots</div>
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
@@ -38,9 +38,7 @@ function resetPrestigeStore() {
|
||||
totalInsight: 500,
|
||||
loopInsight: 0,
|
||||
prestigeUpgrades: {},
|
||||
memorySlots: 3,
|
||||
pactSlots: 1,
|
||||
memories: [],
|
||||
defeatedGuardians: [],
|
||||
signedPacts: [],
|
||||
signedPactDetails: {},
|
||||
@@ -211,46 +209,6 @@ describe('PrestigeStore', () => {
|
||||
}
|
||||
});
|
||||
|
||||
it('should increase memorySlots with deepMemory', () => {
|
||||
usePrestigeStore.setState({ insight: 2000 });
|
||||
const before = usePrestigeStore.getState().memorySlots;
|
||||
const deepResult = usePrestigeStore.getState().doPrestige('deepMemory');
|
||||
expect(deepResult.success).toBe(true);
|
||||
expect(usePrestigeStore.getState().memorySlots).toBe(before + 1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('addMemory / removeMemory', () => {
|
||||
it('should add a memory when slots available', () => {
|
||||
usePrestigeStore.getState().addMemory({ skillId: 'manaFlow', level: 3, tier: 1, upgrades: [] });
|
||||
expect(usePrestigeStore.getState().memories.length).toBe(1);
|
||||
});
|
||||
|
||||
it('should not add duplicate memory', () => {
|
||||
usePrestigeStore.getState().addMemory({ skillId: 'manaFlow', level: 3, tier: 1, upgrades: [] });
|
||||
usePrestigeStore.getState().addMemory({ skillId: 'manaFlow', level: 5, tier: 1, upgrades: [] });
|
||||
expect(usePrestigeStore.getState().memories.length).toBe(1);
|
||||
});
|
||||
|
||||
it('should not exceed memory slots', () => {
|
||||
usePrestigeStore.setState({ memorySlots: 1 });
|
||||
usePrestigeStore.getState().addMemory({ skillId: 'manaFlow', level: 1, tier: 1, upgrades: [] });
|
||||
usePrestigeStore.getState().addMemory({ skillId: 'manaSpring', level: 1, tier: 1, upgrades: [] });
|
||||
expect(usePrestigeStore.getState().memories.length).toBe(1);
|
||||
});
|
||||
|
||||
it('should remove memory by skillId', () => {
|
||||
usePrestigeStore.getState().addMemory({ skillId: 'manaFlow', level: 3, tier: 1, upgrades: [] });
|
||||
usePrestigeStore.getState().removeMemory('manaFlow');
|
||||
expect(usePrestigeStore.getState().memories.length).toBe(0);
|
||||
});
|
||||
|
||||
it('should clear all memories', () => {
|
||||
usePrestigeStore.getState().addMemory({ skillId: 'manaFlow', level: 1, tier: 1, upgrades: [] });
|
||||
usePrestigeStore.getState().addMemory({ skillId: 'manaSpring', level: 1, tier: 1, upgrades: [] });
|
||||
usePrestigeStore.getState().clearMemories();
|
||||
expect(usePrestigeStore.getState().memories.length).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('defeatGuardian / signedPacts', () => {
|
||||
@@ -362,10 +320,10 @@ describe('PrestigeStore', () => {
|
||||
|
||||
describe('resetPrestigeForNewLoop', () => {
|
||||
it('should preserve insight and upgrades, reset loop state', () => {
|
||||
usePrestigeStore.getState().resetPrestigeForNewLoop(200, { manaWell: 2 }, [], 4);
|
||||
usePrestigeStore.getState().resetPrestigeForNewLoop(200, { manaWell: 2 });
|
||||
expect(usePrestigeStore.getState().insight).toBe(200);
|
||||
expect(usePrestigeStore.getState().prestigeUpgrades).toEqual({ manaWell: 2 });
|
||||
expect(usePrestigeStore.getState().memorySlots).toBe(4);
|
||||
|
||||
expect(usePrestigeStore.getState().defeatedGuardians).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -64,9 +64,7 @@ function resetAllStores() {
|
||||
totalInsight: 0,
|
||||
loopInsight: 0,
|
||||
prestigeUpgrades: {},
|
||||
memorySlots: 3,
|
||||
pactSlots: 1,
|
||||
memories: [],
|
||||
defeatedGuardians: [],
|
||||
signedPacts: [],
|
||||
signedPactDetails: {},
|
||||
|
||||
@@ -4,7 +4,6 @@ import type { PrestigeDef } from '../types';
|
||||
export const PRESTIGE_DEF: Record<string, PrestigeDef> = {
|
||||
manaWell: { name: "Mana Well", desc: "+500 starting max mana", max: 5, cost: 500 },
|
||||
manaFlow: { name: "Mana Flow", desc: "+0.5 regen/sec permanently", max: 10, cost: 750 },
|
||||
deepMemory: { name: "Deep Memory", desc: "+1 memory slot", max: 5, cost: 1000 },
|
||||
insightAmp: { name: "Insight Amp", desc: "+25% insight gain", max: 4, cost: 1500 },
|
||||
spireKey: { name: "Spire Key", desc: "Start at floor +2", max: 5, cost: 4000 },
|
||||
temporalEcho: { name: "Temporal Echo", desc: "+10% mana generation", max: 5, cost: 3000 },
|
||||
|
||||
@@ -39,8 +39,6 @@ export const createStartNewLoop = (set: (state: Partial<GameCoordinatorState>) =
|
||||
usePrestigeStore.getState().resetPrestigeForNewLoop(
|
||||
total,
|
||||
pu,
|
||||
prestigeState.memories,
|
||||
3 + (pu.deepMemory || 0)
|
||||
);
|
||||
usePrestigeStore.getState().incrementLoopCount();
|
||||
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
// ─── Prestige Store ───────────────────────────────────────────────────────────
|
||||
// Handles insight, prestige upgrades, memories, loops, pacts
|
||||
// Handles insight, prestige upgrades, loops, pacts
|
||||
|
||||
import { create } from 'zustand';
|
||||
import { persist } from 'zustand/middleware';
|
||||
import { createSafeStorage } from '../utils/safe-persist';
|
||||
import type { Memory } from '../types';
|
||||
import { PRESTIGE_DEF } from '../constants';
|
||||
import { getGuardianForFloor } from '../data/guardian-encounters';
|
||||
import { ok, okVoid, fail, ErrorCode } from '../utils/result';
|
||||
@@ -23,12 +22,8 @@ export interface PrestigeState {
|
||||
|
||||
// Prestige upgrades
|
||||
prestigeUpgrades: Record<string, number>;
|
||||
memorySlots: number;
|
||||
pactSlots: number;
|
||||
|
||||
// Memories (skills preserved across loops)
|
||||
memories: Memory[];
|
||||
|
||||
// Guardian pacts
|
||||
defeatedGuardians: number[];
|
||||
signedPacts: number[];
|
||||
@@ -46,9 +41,6 @@ export interface PrestigeState {
|
||||
|
||||
export interface PrestigeActions {
|
||||
doPrestige: (id: string) => Result<void>;
|
||||
addMemory: (memory: Memory) => void;
|
||||
removeMemory: (skillId: string) => void;
|
||||
clearMemories: () => void;
|
||||
startPactRitual: (floor: number, rawMana: number) => Result<void>;
|
||||
cancelPactRitual: () => void;
|
||||
completePactRitual: (addLog: (msg: string) => void) => void;
|
||||
@@ -65,8 +57,6 @@ export interface PrestigeActions {
|
||||
resetPrestigeForNewLoop: (
|
||||
totalInsight: number,
|
||||
prestigeUpgrades: Record<string, number>,
|
||||
memories: Memory[],
|
||||
memorySlots: number
|
||||
) => void;
|
||||
|
||||
// Loop management
|
||||
@@ -98,9 +88,7 @@ const initialState: PrestigeState = {
|
||||
totalInsight: 0,
|
||||
loopInsight: 0,
|
||||
prestigeUpgrades: {},
|
||||
memorySlots: 3,
|
||||
pactSlots: 1,
|
||||
memories: [],
|
||||
defeatedGuardians: [],
|
||||
signedPacts: [],
|
||||
signedPactDetails: {},
|
||||
@@ -126,30 +114,11 @@ export const usePrestigeStore = create<PrestigeStore>()(
|
||||
set({
|
||||
insight: state.insight - pd.cost,
|
||||
prestigeUpgrades: newPU,
|
||||
memorySlots: id === 'deepMemory' ? state.memorySlots + 1 : state.memorySlots,
|
||||
pactSlots: id === 'pactBinding' ? state.pactSlots + 1 : state.pactSlots,
|
||||
});
|
||||
return okVoid();
|
||||
},
|
||||
|
||||
addMemory: (memory: Memory) => {
|
||||
const state = get();
|
||||
if (state.memories.length >= state.memorySlots) return;
|
||||
if (state.memories.some(m => m.skillId === memory.skillId)) return;
|
||||
|
||||
set({ memories: [...state.memories, memory] });
|
||||
},
|
||||
|
||||
removeMemory: (skillId: string) => {
|
||||
set((state) => ({
|
||||
memories: state.memories.filter(m => m.skillId !== skillId),
|
||||
}));
|
||||
},
|
||||
|
||||
clearMemories: () => {
|
||||
set({ memories: [] });
|
||||
},
|
||||
|
||||
startPactRitual: (floor: number, rawMana: number) => {
|
||||
const state = get();
|
||||
const guardian = getGuardianForFloor(floor);
|
||||
@@ -242,14 +211,10 @@ export const usePrestigeStore = create<PrestigeStore>()(
|
||||
resetPrestigeForNewLoop: (
|
||||
totalInsight: number,
|
||||
prestigeUpgrades: Record<string, number>,
|
||||
memories: Memory[],
|
||||
memorySlots: number
|
||||
) => {
|
||||
set({
|
||||
insight: totalInsight,
|
||||
prestigeUpgrades,
|
||||
memories,
|
||||
memorySlots,
|
||||
// Reset loop-specific state
|
||||
defeatedGuardians: [],
|
||||
signedPacts: [],
|
||||
@@ -304,9 +269,7 @@ export const usePrestigeStore = create<PrestigeStore>()(
|
||||
totalInsight: state.totalInsight,
|
||||
loopInsight: state.loopInsight,
|
||||
prestigeUpgrades: state.prestigeUpgrades,
|
||||
memorySlots: state.memorySlots,
|
||||
pactSlots: state.pactSlots,
|
||||
memories: state.memories,
|
||||
defeatedGuardians: state.defeatedGuardians,
|
||||
signedPacts: state.signedPacts,
|
||||
signedPactDetails: state.signedPactDetails,
|
||||
|
||||
@@ -73,10 +73,3 @@ export interface SkillUpgradeChoice {
|
||||
};
|
||||
}
|
||||
|
||||
// ─── New: Memory Type Definition ─────────────────────────────────────────────
|
||||
export interface Memory {
|
||||
skillId: string;
|
||||
level: number;
|
||||
tier: number;
|
||||
upgrades: string[];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user