diff --git a/docs/circular-deps.txt b/docs/circular-deps.txt index af4d847..56435d9 100644 --- a/docs/circular-deps.txt +++ b/docs/circular-deps.txt @@ -1,5 +1,5 @@ # Circular Dependencies -Generated: 2026-06-12T08:05:45.261Z +Generated: 2026-06-12T10:15:03.641Z Found: 4 circular chain(s) — these MUST be fixed before modifying involved files. 1. 1) data/guardian-encounters.ts > data/guardian-procedural.ts diff --git a/docs/dependency-graph.json b/docs/dependency-graph.json index 4f7188b..a440f0a 100644 --- a/docs/dependency-graph.json +++ b/docs/dependency-graph.json @@ -1,6 +1,6 @@ { "_meta": { - "generated": "2026-06-12T08:05:43.098Z", + "generated": "2026-06-12T10:15:01.393Z", "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." }, diff --git a/src/lib/game/__tests__/conversion-pause-bug-regression.test.ts b/src/lib/game/__tests__/conversion-pause-bug-regression.test.ts index 515bcdb..770bb61 100644 --- a/src/lib/game/__tests__/conversion-pause-bug-regression.test.ts +++ b/src/lib/game/__tests__/conversion-pause-bug-regression.test.ts @@ -41,9 +41,9 @@ describe('Bug #348 — conversion pause regression', () => { rawGrossRegen, }); - // Earth conversion: baseRate=22.04, rawCost=100 - // rawDrain = 22.04 * 1.0 * 1.0 * 1.0 * 100 = 2204/hr - // 2204 < 3342.95 => should NOT be paused + // Earth conversion: baseRate=22.04, rawCost=2 + // rawDrain = 22.04 * 1.0 * 1.0 * 1.0 * 2 = 44.08/hr + // 44.08 < 3342.95 => should NOT be paused const earthEntry = result.rates['earth']; expect(earthEntry).toBeDefined(); expect(earthEntry.paused).toBe(false); diff --git a/src/lib/game/__tests__/mana-conversion-component-deduction.test.ts b/src/lib/game/__tests__/mana-conversion-component-deduction.test.ts index 9baf45d..07383d1 100644 --- a/src/lib/game/__tests__/mana-conversion-component-deduction.test.ts +++ b/src/lib/game/__tests__/mana-conversion-component-deduction.test.ts @@ -32,14 +32,14 @@ describe('Mana Conversion — component consumption deduction (bug #293)', () => }); // Fire is used as a component for metal conversion - // metal rate = 0.35, fire component cost = 30 per unit - // elementDrain[fire] = 0.35 * 30 = 10.5/hr + // metal rate = 0.35, fire component cost = 6 per unit (3 * distance 2) + // elementDrain[fire] = 0.35 * 6 = 2.1/hr expect(result.elementDrain['fire']).toBeGreaterThan(0); - expect(result.elementDrain['fire']).toBeCloseTo(0.35 * 30, 5); + expect(result.elementDrain['fire']).toBeCloseTo(0.35 * 6, 5); // Earth is also used as a component for metal conversion expect(result.elementDrain['earth']).toBeGreaterThan(0); - expect(result.elementDrain['earth']).toBeCloseTo(0.35 * 30, 5); + expect(result.elementDrain['earth']).toBeCloseTo(0.35 * 6, 5); }); it('should compute elementRegen as produced - drained', () => { @@ -65,7 +65,7 @@ describe('Mana Conversion — component consumption deduction (bug #293)', () => rawGrossRegen: 10000, }); - // Fire: produced = 0.5/hr, drained = 0.35 * 30 = 10.5/hr + // Fire: produced = 0.5/hr, drained = 0.35 * 6 = 2.1/hr const fireEntry = result.rates['fire']; expect(fireEntry.finalRate).toBeCloseTo(0.5, 5); @@ -76,7 +76,7 @@ describe('Mana Conversion — component consumption deduction (bug #293)', () => // Verify net: produced - drained const fireProduced = fireEntry.finalRate; const fireDrained = result.elementDrain['fire'] || 0; - expect(fireProduced - fireDrained).toBeCloseTo(0.5 - 10.5, 5); + expect(fireProduced - fireDrained).toBeCloseTo(0.5 - 2.1, 5); }); it('should have zero elementDrain when element is not used as component', () => { @@ -135,15 +135,15 @@ describe('Mana Conversion — component consumption deduction (bug #293)', () => rawGrossRegen: 10000, }); - // Fire: produced = 0.5, drained by metal (0.35 * 30 = 10.5) and lightning (0.35 * 30 = 10.5) - // Total fire drain = 10.5 + 10.5 = 21.0 - expect(result.elementDrain['fire']).toBeCloseTo(21.0, 5); + // Fire: produced = 0.5, drained by metal (0.35 * 6 = 2.1) and lightning (0.35 * 6 = 2.1) + // Total fire drain = 2.1 + 2.1 = 4.2 + expect(result.elementDrain['fire']).toBeCloseTo(4.2, 5); - // Earth: produced = 0 (no earth discipline), drained by metal (0.35 * 30 = 10.5) - expect(result.elementDrain['earth']).toBeCloseTo(10.5, 5); + // Earth: produced = 0 (no earth discipline), drained by metal (0.35 * 6 = 2.1) + expect(result.elementDrain['earth']).toBeCloseTo(2.1, 5); - // Air: produced = 0 (no air discipline), drained by lightning (0.35 * 30 = 10.5) - expect(result.elementDrain['air']).toBeCloseTo(10.5, 5); + // Air: produced = 0 (no air discipline), drained by lightning (0.35 * 6 = 2.1) + expect(result.elementDrain['air']).toBeCloseTo(2.1, 5); // Metal: produced = 0.35, not consumed by anything in this setup expect(result.elementDrain['metal'] || 0).toBe(0); diff --git a/src/lib/game/data/conversion-costs.ts b/src/lib/game/data/conversion-costs.ts index eea9b2c..7036e72 100644 --- a/src/lib/game/data/conversion-costs.ts +++ b/src/lib/game/data/conversion-costs.ts @@ -3,8 +3,8 @@ // Costs are deducted from regen (not from the mana pool). // // For a destination element at distance d: -// rawCost = 10^(d+1) -// componentCost = 10 * (d+1) per component +// rawCost = 2 * d +// componentCost = 3 * d per component import type { ElementRecipe } from '../types'; @@ -20,11 +20,11 @@ export interface ConversionCost { } function computeRawCost(distance: number): number { - return Math.pow(10, distance + 1); + return 2 * distance; } function computeComponentCost(distance: number): number { - return 10 * (distance + 1); + return 3 * distance; } /** Build a ConversionCost for a base element (distance 1, no components) */ @@ -32,14 +32,14 @@ function baseElementCost(element: string): ConversionCost { return { element, distance: 1, - rawCost: computeRawCost(1), // 100 + rawCost: computeRawCost(1), // 2 componentCosts: {}, }; } /** Build a ConversionCost for a composite element (distance 2) */ function compositeElementCost(element: string, components: string[]): ConversionCost { - const costPerComponent = computeComponentCost(2); // 30 each + const costPerComponent = computeComponentCost(2); // 6 each const componentCosts: Record = {}; for (const c of components) { componentCosts[c] = (componentCosts[c] || 0) + costPerComponent; @@ -47,14 +47,14 @@ function compositeElementCost(element: string, components: string[]): Conversion return { element, distance: 2, - rawCost: computeRawCost(2), // 1,000 + rawCost: computeRawCost(2), // 4 componentCosts, }; } /** Build a ConversionCost for an exotic element (distance 3) */ function exoticElementCost(element: string, components: string[]): ConversionCost { - const costPerComponent = computeComponentCost(3); // 40 each + const costPerComponent = computeComponentCost(3); // 9 each const componentCosts: Record = {}; for (const c of components) { componentCosts[c] = (componentCosts[c] || 0) + costPerComponent; @@ -62,14 +62,14 @@ function exoticElementCost(element: string, components: string[]): ConversionCos return { element, distance: 3, - rawCost: computeRawCost(3), // 10,000 + rawCost: computeRawCost(3), // 6 componentCosts, }; } /** Build a ConversionCost for time (distance 4) */ function timeElementCost(element: string, components: string[]): ConversionCost { - const costPerComponent = computeComponentCost(4); // 50 each + const costPerComponent = computeComponentCost(4); // 12 each const componentCosts: Record = {}; for (const c of components) { componentCosts[c] = (componentCosts[c] || 0) + costPerComponent; @@ -77,7 +77,7 @@ function timeElementCost(element: string, components: string[]): ConversionCost return { element, distance: 4, - rawCost: computeRawCost(4), // 100,000 + rawCost: computeRawCost(4), // 8 componentCosts, }; }