refactor: remove skill system leftovers, migrate click mana to discipline perk
Build and Publish Mana Loop Docker Image / build-and-publish (push) Successful in 1m30s

- Simplified getMeditationBonus() to continuous ramp formula
- Added click-mana capped perk to Mana Circulation discipline
- Removed manaWell/manaFlow/manaSpring skill reads and prestige upgrades
- Removed all skill fields from GameState and GameActionType
- Updated all call sites and tests (916 tests passing)

Closes #174
This commit is contained in:
2026-05-28 11:50:06 +02:00
parent b5996d5b6e
commit 5578721992
22 changed files with 135 additions and 311 deletions
+8 -45
View File
@@ -13,10 +13,7 @@ export interface DisciplineBonuses {
// ─── Mana Params ────────────────────────────────────────────────────────────
export interface ManaComputeParams {
skills?: Record<string, number>;
prestigeUpgrades?: Record<string, number>;
skillUpgrades?: Record<string, string[]>;
skillTiers?: Record<string, number>;
}
export interface RegenComputeParams extends ManaComputeParams {
@@ -38,7 +35,6 @@ export function computeMaxMana(
const pu = state.prestigeUpgrades || {};
const base =
100 +
((state.skills || {}).manaWell || 0) * 100 +
(pu.manaWell || 0) * 500 +
(discipline?.bonuses?.maxManaBonus || 0);
@@ -51,7 +47,7 @@ export function computeMaxMana(
// ─── Regen ────────────────────────────────────────────────────────────────────
export function computeRegen(
state: Pick<RegenComputeParams, 'skills' | 'prestigeUpgrades' | 'attunements'> & Partial<Pick<RegenComputeParams, 'skillUpgrades' | 'skillTiers'>>,
state: Pick<RegenComputeParams, 'prestigeUpgrades' | 'attunements'>,
effects?: ComputedEffects,
discipline?: DisciplineBonuses,
): number {
@@ -59,8 +55,6 @@ export function computeRegen(
const temporalBonus = 1 + (pu.temporalEcho || 0) * 0.1;
const base =
2 +
((state.skills || {}).manaFlow || 0) * 1 +
((state.skills || {}).manaSpring || 0) * 2 +
((pu || {}).manaFlow || 0) * 0.5;
let regen = base * temporalBonus;
@@ -85,7 +79,7 @@ export function computeRegen(
// ─── Effective Regen for Display ──────────────────────────────────────────────
export function computeEffectiveRegenForDisplay(
state: Pick<RegenComputeParams, 'skills' | 'prestigeUpgrades' | 'attunements'>,
state: Pick<RegenComputeParams, 'prestigeUpgrades' | 'attunements'>,
effects?: ComputedEffects,
discipline?: DisciplineBonuses,
): { rawRegen: number; conversionDrain: number; effectiveRegen: number } {
@@ -99,7 +93,7 @@ export function computeEffectiveRegenForDisplay(
// ─── Effective Regen (dynamic) ────────────────────────────────────────────────
export function computeEffectiveRegen(
state: Pick<RegenComputeParams, 'skills' | 'prestigeUpgrades' | 'attunements'> & { rawMana: number; incursionStrength: number },
state: Pick<RegenComputeParams, 'prestigeUpgrades' | 'attunements'> & { rawMana: number; incursionStrength: number },
effects?: ComputedEffects,
discipline?: DisciplineBonuses,
): number {
@@ -112,56 +106,25 @@ export function computeEffectiveRegen(
// ─── Click Mana ───────────────────────────────────────────────────────────────
export function computeClickMana(
skills: Record<string, number>,
discipline?: DisciplineBonuses,
): number {
const skillTap = (skills.manaTap || 0) * 1;
const skillSurge = (skills.manaSurge || 0) * 3;
const discClickMult = discipline?.bonuses?.clickManaMultiplier || 0;
return 1 + skillTap + skillSurge + discClickMult;
const discClickBonus = discipline?.bonuses?.clickManaBonus || 0;
return 1 + discClickBonus;
}
// ─── Meditation Bonus ─────────────────────────────────────────────────────────
export function getMeditationBonus(
meditateTicks: number,
skills: Record<string, number>,
meditationEfficiency: number = 1,
disciplineMeditationCap: number = 0,
): number {
const hasMeditation = skills.meditation === 1;
const hasDeepTrance = skills.deepTrance === 1;
const hasVoidMeditation = skills.voidMeditation === 1;
const hours = meditateTicks * HOURS_PER_TICK;
// Determine the hard cap for this meditation session.
// disciplineMeditationCap adds +0.5 per point (e.g. from Mana Circulation discipline).
// Base max is 5.0 (Void Meditation), each discipline bonus adds +0.5.
// Continuous ramp: 1 + (hours / 8) * 4, capped at 5.0 + disciplineMeditationCap
const maxMultiplier = 5.0 + disciplineMeditationCap;
// Base meditation: ramps up over 4 hours, capped at 1.5x or discipline cap
let bonus = 1 + Math.min(hours / 4, 0.5);
bonus = Math.min(bonus, maxMultiplier);
// With Meditation Focus: up to 2.5x after 4 hours
if (hasMeditation && hours >= 4) {
bonus = Math.min(2.5, maxMultiplier);
}
// With Deep Trance: up to 3.0x after 6 hours
if (hasDeepTrance && hours >= 6) {
bonus = Math.min(3.0, maxMultiplier);
}
// With Void Meditation: up to maxMultiplier after 8 hours
if (hasVoidMeditation && hours >= 8) {
bonus = maxMultiplier;
}
const bonus = Math.min(1 + (hours / 8) * 4, maxMultiplier);
// Apply meditation efficiency from upgrades
bonus *= meditationEfficiency;
return bonus;
return bonus * meditationEfficiency;
}