[priority: high] Bloated state types — GameState (71 fields), CombatState (58), PrestigeState (39) #102

Closed
opened 2026-05-20 10:59:26 +02:00 by Anexim · 4 comments
Owner

Severity: High — god-objects make it impossible to reason about state ownership, increase coupling, and cause unnecessary re-renders.

Findings:

  • GameState has 71 fields covering time, mana, elements, spells, skills, equipment, crafting, scheduling, golemancy, achievements, combat, prestige, pacts, logs
  • CombatState has 58 fields
  • PrestigeState has 39 fields
  • ManaState has 24 fields plus 15+ action methods
  • DisciplineCardProps has 15 fields — component doing too many things

Affected files:

  • src/lib/game/types/game.ts
  • src/lib/game/stores/combat-state.types.ts
  • src/lib/game/stores/prestigeStore.ts
  • src/lib/game/stores/manaStore.ts
  • src/components/game/tabs/DisciplinesTab.tsx

Suggested fix: The modular stores already split these at the store level — align the types. Each store should have its own state type with only domain-relevant fields. Remove the monolithic GameState type. Split wide store interfaces into State and Actions types.

Confidence: High
Dimension: design_coherence (score: 58.0%)

**Severity:** High — god-objects make it impossible to reason about state ownership, increase coupling, and cause unnecessary re-renders. **Findings:** - `GameState` has 71 fields covering time, mana, elements, spells, skills, equipment, crafting, scheduling, golemancy, achievements, combat, prestige, pacts, logs - `CombatState` has 58 fields - `PrestigeState` has 39 fields - `ManaState` has 24 fields plus 15+ action methods - `DisciplineCardProps` has 15 fields — component doing too many things **Affected files:** - `src/lib/game/types/game.ts` - `src/lib/game/stores/combat-state.types.ts` - `src/lib/game/stores/prestigeStore.ts` - `src/lib/game/stores/manaStore.ts` - `src/components/game/tabs/DisciplinesTab.tsx` **Suggested fix:** The modular stores already split these at the store level — align the types. Each store should have its own state type with only domain-relevant fields. Remove the monolithic `GameState` type. Split wide store interfaces into State and Actions types. **Confidence:** High **Dimension:** design_coherence (score: 58.0%)
Anexim added the ai:todo label 2026-05-20 10:59:26 +02:00
n8n-gitea was assigned by Anexim 2026-05-20 10:59:26 +02:00
Author
Owner

Starting work on issue #102: Bloated state types. Will analyze the current state types and split them into domain-specific types aligned with the modular stores.

Starting work on issue #102: Bloated state types. Will analyze the current state types and split them into domain-specific types aligned with the modular stores.
Author
Owner

Analysis Complete

Current State

GameState (71 fields in types/game.ts): Legacy monolithic type still used by crafting-actions/ utility files. The modular stores already split this at the store level. Usage:

  • crafting-actions/application-actions.ts — uses GameState for get/set
  • crafting-actions/computed-getters.ts — uses GameState for get
  • crafting-actions/crafting-equipment-actions.ts — uses GameState for get/set
  • crafting-actions/design-actions.ts — uses GameState for get/set
  • crafting-actions/disenchant-actions.ts — uses GameState for get/set
  • crafting-actions/equipment-actions.ts — uses GameState for get/set
  • utils/combat-utils.ts — uses Pick<GameState, ...> for specific field subsets
  • utils/mana-utils.ts — uses Pick<GameState, ...> for specific field subsets

CombatState (58 fields in stores/combat-state.types.ts): Mixes 16 data fields + 26 action methods in one interface. Used by combatStore.ts, combat-actions.ts, tick-pipeline.ts, stores/index.ts.

PrestigeState (39 fields in stores/prestigeStore.ts): Mixes 13 data fields + 17 action methods. Used by tick-pipeline.ts, stores/index.ts.

ManaState (24 fields + actions in stores/manaStore.ts): Mixes 4 data fields + 13 action methods. Used by tick-pipeline.ts, stores/index.ts.

DisciplineCardProps (15 fields in DisciplinesTab.tsx): Component props mixing discipline definition data + runtime state + callbacks.

Approach

  1. CombatState: Split into CombatState (data only) + CombatActions. Update combatStore.ts to use combined type. Update tick-pipeline.ts to import data type only.

  2. PrestigeState: Split into PrestigeState (data only) + PrestigeActions. Update prestigeStore.ts and tick-pipeline.ts.

  3. ManaState: Split into ManaState (data only) + ManaActions. Update manaStore.ts and tick-pipeline.ts.

  4. GameState: The crafting-actions/ files that use GameState are legacy utilities. The actual crafting store (craftingStore.ts) already uses CraftingState from craftingStore.types.ts. Update the crafting-actions to use CraftingState instead of GameState where possible, and use more specific Pick<> types for utility functions.

  5. DisciplineCardProps: Split into DisciplineDefinition (static data) + DisciplineRuntimeState (runtime data) + DisciplineCardCallbacks (event handlers).

Starting implementation now.

## Analysis Complete ### Current State **GameState** (71 fields in `types/game.ts`): Legacy monolithic type still used by `crafting-actions/` utility files. The modular stores already split this at the store level. Usage: - `crafting-actions/application-actions.ts` — uses `GameState` for get/set - `crafting-actions/computed-getters.ts` — uses `GameState` for get - `crafting-actions/crafting-equipment-actions.ts` — uses `GameState` for get/set - `crafting-actions/design-actions.ts` — uses `GameState` for get/set - `crafting-actions/disenchant-actions.ts` — uses `GameState` for get/set - `crafting-actions/equipment-actions.ts` — uses `GameState` for get/set - `utils/combat-utils.ts` — uses `Pick<GameState, ...>` for specific field subsets - `utils/mana-utils.ts` — uses `Pick<GameState, ...>` for specific field subsets **CombatState** (58 fields in `stores/combat-state.types.ts`): Mixes 16 data fields + 26 action methods in one interface. Used by `combatStore.ts`, `combat-actions.ts`, `tick-pipeline.ts`, `stores/index.ts`. **PrestigeState** (39 fields in `stores/prestigeStore.ts`): Mixes 13 data fields + 17 action methods. Used by `tick-pipeline.ts`, `stores/index.ts`. **ManaState** (24 fields + actions in `stores/manaStore.ts`): Mixes 4 data fields + 13 action methods. Used by `tick-pipeline.ts`, `stores/index.ts`. **DisciplineCardProps** (15 fields in `DisciplinesTab.tsx`): Component props mixing discipline definition data + runtime state + callbacks. ### Approach 1. **CombatState**: Split into `CombatState` (data only) + `CombatActions`. Update `combatStore.ts` to use combined type. Update `tick-pipeline.ts` to import data type only. 2. **PrestigeState**: Split into `PrestigeState` (data only) + `PrestigeActions`. Update `prestigeStore.ts` and `tick-pipeline.ts`. 3. **ManaState**: Split into `ManaState` (data only) + `ManaActions`. Update `manaStore.ts` and `tick-pipeline.ts`. 4. **GameState**: The `crafting-actions/` files that use `GameState` are legacy utilities. The actual crafting store (`craftingStore.ts`) already uses `CraftingState` from `craftingStore.types.ts`. Update the crafting-actions to use `CraftingState` instead of `GameState` where possible, and use more specific `Pick<>` types for utility functions. 5. **DisciplineCardProps**: Split into `DisciplineDefinition` (static data) + `DisciplineRuntimeState` (runtime data) + `DisciplineCardCallbacks` (event handlers). Starting implementation now.
Author
Owner

Implementation Complete

Changes Made

1. CombatState split (stores/combat-state.types.ts):

  • Separated into CombatState (16 data fields) + CombatActions (25 action methods) + CombatStore (combined type)
  • Updated combatStore.ts to use CombatStore type
  • Updated combat-actions.ts to use CombatStore for get/set

2. PrestigeState split (stores/prestigeStore.ts):

  • Separated into PrestigeState (13 data fields) + PrestigeActions (17 action methods) + PrestigeStore (combined type)
  • Removed actions from the data interface

3. ManaState split (stores/manaStore.ts):

  • Separated into ManaState (4 data fields) + ManaActions (13 action methods) + ManaStore (combined type)
  • Removed actions from the data interface

4. GameState deprecated (types/game.ts, types/index.ts, types.ts):

  • Removed GameState from all barrel exports
  • Updated crafting-actions/ files to use CraftingState instead of GameState
  • Updated utility functions in combat-utils.ts and mana-utils.ts to use focused parameter interfaces instead of Pick<GameState, ...>
  • Created new focused interfaces: DamageCalcParams, InsightCalcParams, DPSCalcParams, ManaComputeParams, RegenComputeParams

5. DisciplineCardProps split (DisciplinesTab.tsx):

  • Separated 15-field monolithic interface into:
    • DisciplineCardDefinition (10 static data fields)
    • DisciplineCardRuntime (3 runtime state fields)
    • DisciplineCardCallbacks (1 callback)

6. Store index updated (stores/index.ts):

  • Now exports both State and Actions types for each store

Test Results

  • 27 test files pass, 1 pre-existing failure (spire-utils, unrelated to changes)
  • 637 tests pass, 2 pre-existing failures
  • TypeScript errors reduced from 78 to 75
## Implementation Complete ### Changes Made **1. CombatState split** (`stores/combat-state.types.ts`): - Separated into `CombatState` (16 data fields) + `CombatActions` (25 action methods) + `CombatStore` (combined type) - Updated `combatStore.ts` to use `CombatStore` type - Updated `combat-actions.ts` to use `CombatStore` for get/set **2. PrestigeState split** (`stores/prestigeStore.ts`): - Separated into `PrestigeState` (13 data fields) + `PrestigeActions` (17 action methods) + `PrestigeStore` (combined type) - Removed actions from the data interface **3. ManaState split** (`stores/manaStore.ts`): - Separated into `ManaState` (4 data fields) + `ManaActions` (13 action methods) + `ManaStore` (combined type) - Removed actions from the data interface **4. GameState deprecated** (`types/game.ts`, `types/index.ts`, `types.ts`): - Removed `GameState` from all barrel exports - Updated `crafting-actions/` files to use `CraftingState` instead of `GameState` - Updated utility functions in `combat-utils.ts` and `mana-utils.ts` to use focused parameter interfaces instead of `Pick<GameState, ...>` - Created new focused interfaces: `DamageCalcParams`, `InsightCalcParams`, `DPSCalcParams`, `ManaComputeParams`, `RegenComputeParams` **5. DisciplineCardProps split** (`DisciplinesTab.tsx`): - Separated 15-field monolithic interface into: - `DisciplineCardDefinition` (10 static data fields) - `DisciplineCardRuntime` (3 runtime state fields) - `DisciplineCardCallbacks` (1 callback) **6. Store index updated** (`stores/index.ts`): - Now exports both State and Actions types for each store ### Test Results - 27 test files pass, 1 pre-existing failure (spire-utils, unrelated to changes) - 637 tests pass, 2 pre-existing failures - TypeScript errors reduced from 78 to 75
Author
Owner

Issue #102 resolved. All changes committed and pushed to master (commit 8a7ddaa). Bloated state types have been split into focused State + Actions interfaces aligned with the modular stores.

Issue #102 resolved. All changes committed and pushed to master (commit 8a7ddaa). Bloated state types have been split into focused State + Actions interfaces aligned with the modular stores.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Anexim/Mana-Loop#102