[High] [Bug] Discipline auto-pause flag not cleared on deactivate→reactivate, causing silent failure #351

Closed
opened 2026-06-10 14:49:16 +02:00 by Anexim · 2 comments
Owner

Bug Summary

When a discipline auto-pauses due to insufficient mana and the user manually deactivates then reactivates it, the autoPaused flag is not cleared. The discipline appears active (button shows "Stop Practicing", it's in activeIds) but processTick silently skips it because disc.autoPaused === true. No mana is drained and no XP is accrued.

Root Cause

In src/lib/game/stores/discipline-slice.ts, the activate() method has two code paths:

  1. Direct un-pause (discipline still in activeIds): Correctly clears autoPaused: false
  2. New activation (discipline was deactivated, not in activeIds): Does { ...discState, paused: false } which preserves the stale autoPaused: true from the previous auto-pause

The deactivate() method sets paused: true but does NOT clear autoPaused. When activate() later spreads the existing state, autoPaused: true persists.

Reproduction Steps

  1. Activate a discipline (e.g., raw-mastery) with sufficient mana
  2. Let mana drain to 0 → discipline auto-pauses (autoPaused: true, still in activeIds)
  3. Restore mana in the store
  4. Click "Stop Practicing" → deactivate() sets paused: true, removes from activeIds
  5. Click "Start Practicing" → activate() re-adds to activeIds with paused: false but autoPaused: true
  6. Result: Discipline appears active but processTick skips it (no drain, no XP)

Evidence

Reproduction test at src/lib/game/__tests__/discipline-auto-pause-reactivate-bug.test.ts:

  • 2 tests FAIL on the deactivate→reactivate path (both raw and element disciplines)
  • 1 test PASSES on the direct un-pause path (discipline stays in activeIds)

Severity

High — Core gameplay loop is broken. The discipline system is a primary progression mechanic. Players lose progress silently with no feedback.

Files Involved

  • src/lib/game/stores/discipline-slice.tsactivate() and deactivate() methods
  • src/components/game/tabs/DisciplineCard.tsx — UI shows "Stop Practicing" for auto-paused disciplines (secondary issue: autoPaused state not displayed)

Suggested Fix

In activate(), the new activation path should clear autoPaused:

const discState = existing || { id, xp: 0, paused: false };
return {
  disciplines: { ...s.disciplines, [id]: { ...discState, paused: false, autoPaused: false } } },
  activeIds: [...activeIds, id],
};

Also consider clearing autoPaused in deactivate() for defense-in-depth.

## Bug Summary When a discipline auto-pauses due to insufficient mana and the user manually deactivates then reactivates it, the `autoPaused` flag is not cleared. The discipline appears active (button shows "Stop Practicing", it's in `activeIds`) but `processTick` silently skips it because `disc.autoPaused === true`. No mana is drained and no XP is accrued. ## Root Cause In `src/lib/game/stores/discipline-slice.ts`, the `activate()` method has two code paths: 1. **Direct un-pause** (discipline still in `activeIds`): Correctly clears `autoPaused: false` ✅ 2. **New activation** (discipline was deactivated, not in `activeIds`): Does `{ ...discState, paused: false }` which preserves the stale `autoPaused: true` from the previous auto-pause ❌ The `deactivate()` method sets `paused: true` but does NOT clear `autoPaused`. When `activate()` later spreads the existing state, `autoPaused: true` persists. ## Reproduction Steps 1. Activate a discipline (e.g., `raw-mastery`) with sufficient mana 2. Let mana drain to 0 → discipline auto-pauses (`autoPaused: true`, still in `activeIds`) 3. Restore mana in the store 4. Click "Stop Practicing" → `deactivate()` sets `paused: true`, removes from `activeIds` 5. Click "Start Practicing" → `activate()` re-adds to `activeIds` with `paused: false` but `autoPaused: true` 6. **Result**: Discipline appears active but `processTick` skips it (no drain, no XP) ## Evidence Reproduction test at `src/lib/game/__tests__/discipline-auto-pause-reactivate-bug.test.ts`: - 2 tests FAIL on the deactivate→reactivate path (both raw and element disciplines) - 1 test PASSES on the direct un-pause path (discipline stays in `activeIds`) ## Severity **High** — Core gameplay loop is broken. The discipline system is a primary progression mechanic. Players lose progress silently with no feedback. ## Files Involved - `src/lib/game/stores/discipline-slice.ts` — `activate()` and `deactivate()` methods - `src/components/game/tabs/DisciplineCard.tsx` — UI shows "Stop Practicing" for auto-paused disciplines (secondary issue: `autoPaused` state not displayed) ## Suggested Fix In `activate()`, the new activation path should clear `autoPaused`: ```ts const discState = existing || { id, xp: 0, paused: false }; return { disciplines: { ...s.disciplines, [id]: { ...discState, paused: false, autoPaused: false } } }, activeIds: [...activeIds, id], }; ``` Also consider clearing `autoPaused` in `deactivate()` for defense-in-depth.
Anexim added the ai:todo label 2026-06-10 14:49:16 +02:00
n8n-gitea was assigned by Anexim 2026-06-10 14:49:16 +02:00
Anexim added ai:in-progress and removed ai:todo labels 2026-06-11 09:06:28 +02:00
Author
Owner

Starting work on fixing the discipline auto-pause flag not being cleared on deactivate→reactivate. Investigating the discipline store slice.

Starting work on fixing the discipline auto-pause flag not being cleared on deactivate→reactivate. Investigating the discipline store slice.
Anexim added ai:done and removed ai:in-progress labels 2026-06-11 09:09:33 +02:00
Author
Owner

Fixed. Added autoPaused: false to the discipline deactivation logic in deactivate(). Previously, when a discipline was auto-paused (due to insufficient mana) and then manually deactivated, the autoPaused flag was not cleared. On re-activation, the discipline state still had autoPaused: true which caused the activate function to silently skip re-activation. All 1158 tests pass.

Fixed. Added `autoPaused: false` to the discipline deactivation logic in `deactivate()`. Previously, when a discipline was auto-paused (due to insufficient mana) and then manually deactivated, the `autoPaused` flag was not cleared. On re-activation, the discipline state still had `autoPaused: true` which caused the activate function to silently skip re-activation. All 1158 tests pass.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Anexim/Mana-Loop#351