diff --git a/AGENTS.md b/AGENTS.md
index c727564..e67b03b 100755
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -560,6 +560,10 @@ The following mana types have been **removed** and should **never be re-added**:
- `mental` - Mind/psionic themed (removed for design consistency)
- `force` - Telekinetic themed (removed for design consistency)
+### Removed Features
+- LabTab — permanently removed. Do not re-add under any name.
+ The lab element conversion UI was replaced by attunements.
+
---
## 🔮 Mana Types Overview
diff --git a/docs/project-structure.txt b/docs/project-structure.txt
index 619059c..91acfb7 100644
--- a/docs/project-structure.txt
+++ b/docs/project-structure.txt
@@ -121,7 +121,6 @@ Mana-Loop/
│ │ │ │ ├── FloorControls.tsx
│ │ │ │ ├── GolemancyTab.tsx
│ │ │ │ ├── GuardianPanel.tsx
-│ │ │ │ ├── LabTab.tsx
│ │ │ │ ├── LootTab.tsx
│ │ │ │ ├── MilestoneProgress.tsx
│ │ │ │ ├── PrestigeTab.tsx
@@ -143,7 +142,6 @@ Mana-Loop/
│ │ │ ├── CraftingProgress.tsx
│ │ │ ├── GameContext.tsx
│ │ │ ├── GameToast.tsx
-│ │ │ ├── LabTab.tsx
│ │ │ ├── ManaDisplay.tsx
│ │ │ ├── SkillsTab.tsx
│ │ │ ├── SpellsTab.tsx
diff --git a/src/app/components/LeftPanel.tsx b/src/app/components/LeftPanel.tsx
index f285fd1..0e5873b 100644
--- a/src/app/components/LeftPanel.tsx
+++ b/src/app/components/LeftPanel.tsx
@@ -9,7 +9,7 @@ import { CalendarDisplay } from '@/components/game';
import { DebugName } from '@/lib/game/debug-context';
import { useGameStore, useManaStore, useSkillStore, useCombatStore, useCraftingStore } from '@/lib/game/stores';
import { getUnifiedEffects } from '@/lib/game/effects';
-import { computeMaxMana, computeClickMana, getMeditationBonus } from '@/lib/game/stores';
+import { computeMaxMana, computeRegen, computeClickMana, getMeditationBonus, getIncursionStrength } from '@/lib/game/stores';
export function LeftPanel() {
const [isGathering, setIsGathering] = useState(false);
@@ -23,6 +23,9 @@ export function LeftPanel() {
const skillTiers = useSkillStore((s) => s.skillTiers);
const skillUpgrades = useSkillStore((s) => s.skillUpgrades);
+ const equippedInstances = useCraftingStore((s) => s.equippedInstances);
+ const equipmentInstances = useCraftingStore((s) => s.equipmentInstances);
+
const gatherMana = useGameStore((s) => s.gatherMana);
const day = useGameStore((s) => s.day);
const hour = useGameStore((s) => s.hour);
@@ -70,20 +73,26 @@ export function LeftPanel() {
const upgradeEffects = getUnifiedEffects({
skillUpgrades,
skillTiers,
- equippedInstances: {},
- equipmentInstances: {}
+ equippedInstances,
+ equipmentInstances,
});
const maxMana = computeMaxMana(
{ skills, skillTiers, skillUpgrades },
upgradeEffects
);
+ const baseRegen = computeRegen(
+ { skills, skillTiers, skillUpgrades },
+ upgradeEffects
+ );
const clickMana = computeClickMana({
skills,
skillTiers,
skillUpgrades,
});
const meditationMultiplier = getMeditationBonus(meditateTicks, skills, upgradeEffects.meditationEfficiency);
+ const incursionStrength = getIncursionStrength(day, hour);
+ const effectiveRegen = baseRegen * (1 - incursionStrength) * meditationMultiplier;
return (
@@ -91,7 +100,7 @@ export function LeftPanel() {
s.elements);
- const rawMana = useManaStore((s) => s.rawMana);
- const convertMana = useManaStore((s) => s.convertMana);
- const unlockElement = useManaStore((s) => s.unlockElement);
- const craftComposite = useManaStore((s) => s.craftComposite);
-
- const [convertTarget, setConvertTarget] = useState('fire');
-
- return (
-
- {/* Elemental Mana Display */}
-
-
- Elemental Mana
-
-
-
- {Object.entries(elements)
- .filter(([, state]) => state.unlocked && state.current >= 1)
- .map(([id, state]) => {
- const def = ELEMENTS[id];
- const isSelected = convertTarget === id;
- return (
-
setConvertTarget(id)}
- >
-
{def?.sym}
-
{def?.name}
-
{state.current}/{state.max}
-
- );
- })}
-
-
-
-
- {/* Element Conversion */}
-
-
- Element Conversion
-
-
-
- Convert raw mana to elemental mana (100:1 ratio)
-
-
-
-
-
-
-
-
-
-
- {/* Unlock Elements */}
-
-
- Unlock Elements
-
-
-
- Unlock new elemental affinities (500 mana each)
-
-
-
- {Object.entries(elements)
- .filter(([id, state]) => !state.unlocked && ELEMENTS[id]?.cat !== 'exotic')
- .map(([id]) => {
- const def = ELEMENTS[id];
- return (
-
-
{def?.sym}
-
{def?.name}
-
-
- );
- })}
-
-
-
-
- {/* Composite Crafting */}
-
-
- Composite & Exotic Crafting
-
-
-
- {Object.entries(ELEMENTS)
- .filter(([, def]) => def.recipe)
- .map(([id, def]) => {
- const state = elements[id];
- const recipe = def.recipe!;
- const canCraft = recipe.every(
- (r) => (elements[r]?.current || 0) >= recipe.filter((x) => x === r).length
- );
-
- return (
-
-
-
{def.sym}
-
-
- {def.name}
-
-
{def.cat}
-
-
-
- {recipe.map((r) => ELEMENTS[r]?.sym).join(' + ')}
-
-
-
- );
- })}
-
-
-
-
- );
-}
-
-LabTab.displayName = "LabTab";
diff --git a/src/components/game/index.ts b/src/components/game/index.ts
index 0287707..dafd651 100755
--- a/src/components/game/index.ts
+++ b/src/components/game/index.ts
@@ -5,7 +5,6 @@
export { CraftingTab } from './tabs/CraftingTab';
export { SpireTab } from './tabs/SpireTab';
export { SpellsTab } from './tabs/SpellsTab';
-export { LabTab } from './tabs/LabTab';
export { SkillsTab } from './SkillsTab';
export { StatsTab } from './tabs/StatsTab';
diff --git a/src/components/game/tabs/LabTab.tsx b/src/components/game/tabs/LabTab.tsx
deleted file mode 100755
index 8780cca..0000000
--- a/src/components/game/tabs/LabTab.tsx
+++ /dev/null
@@ -1 +0,0 @@
-export { LabTab } from '../LabTab';
diff --git a/src/components/game/tabs/index.ts b/src/components/game/tabs/index.ts
index bf4fcf3..dc78f37 100755
--- a/src/components/game/tabs/index.ts
+++ b/src/components/game/tabs/index.ts
@@ -4,7 +4,6 @@
export { CraftingTab } from './CraftingTab';
export { SpireTab } from './SpireTab';
export { SpellsTab } from './SpellsTab';
-export { LabTab } from './LabTab';
// SkillsTab is now exported from src/components/game/index.ts
export { SkillsTab } from '../SkillsTab';
export { StatsTab } from './StatsTab';
diff --git a/src/lib/game/stores/skillStore.ts b/src/lib/game/stores/skillStore.ts
index 27abbf6..c07736e 100755
--- a/src/lib/game/stores/skillStore.ts
+++ b/src/lib/game/stores/skillStore.ts
@@ -7,6 +7,7 @@ import { SKILLS_DEF, getStudySpeedMultiplier, getStudyCostMultiplier } from '../
import type { StudyTarget, SkillUpgradeChoice } from '../types';
import { SKILL_EVOLUTION_PATHS, getBaseSkillId } from '../skill-evolution';
import { useCombatStore } from './combatStore';
+import { useManaStore } from './manaStore';
export interface SkillState {
// Skills
@@ -134,6 +135,10 @@ export const useSkillStore = create()(
useCombatStore.getState().setAction('study');
+ if (!isAlreadyPaid && cost > 0) {
+ useManaStore.getState().spendRawMana(cost);
+ }
+
return { started: true, cost: isAlreadyPaid ? 0 : cost };
},