[priority: 4] discipline-slice.ts mutates nested element objects directly — bypasses Zustand reactivity #70

Closed
opened 2026-05-19 09:09:47 +02:00 by Anexim · 2 comments
Owner

Severity: 4 — High
File: src/lib/game/stores/discipline-slice.ts, line 97

Description:
In processTick(), the elements object is shallow-copied, but nested element objects are still references to the originals:

const elements = { ...mana.elements };  // shallow copy
// ...
elements[def.manaType].current -= drain;  // MUTATES the nested object!

This mutation happens outside of Zustand, meaning state changes are invisible to React subscribers and won't trigger re-renders until the next set() call.

Fix: Clone each element before mutation:

elements[def.manaType] = { ...elements[def.manaType], current: elements[def.manaType].current - drain };
**Severity:** 4 — High **File:** `src/lib/game/stores/discipline-slice.ts`, line 97 **Description:** In `processTick()`, the `elements` object is shallow-copied, but nested element objects are still references to the originals: ```ts const elements = { ...mana.elements }; // shallow copy // ... elements[def.manaType].current -= drain; // MUTATES the nested object! ``` This mutation happens **outside of Zustand**, meaning state changes are invisible to React subscribers and won't trigger re-renders until the next `set()` call. **Fix:** Clone each element before mutation: ```ts elements[def.manaType] = { ...elements[def.manaType], current: elements[def.manaType].current - drain }; ```
Anexim added the ai:todo label 2026-05-19 09:09:47 +02:00
n8n-gitea was assigned by Anexim 2026-05-19 09:09:47 +02:00
Author
Owner

Starting work on Issue 70: discipline-slice.ts mutates nested element objects directly, bypassing Zustand reactivity. The shallow copy on line 97 (const elements = { ...mana.elements }) doesn't clone nested objects, so elements[def.manaType].current -= drain mutates the original state. Fix: clone each element before mutation.

Starting work on Issue 70: discipline-slice.ts mutates nested element objects directly, bypassing Zustand reactivity. The shallow copy on line 97 (`const elements = { ...mana.elements }`) doesn't clone nested objects, so `elements[def.manaType].current -= drain` mutates the original state. Fix: clone each element before mutation.
Author
Owner

Fixed: Replaced direct nested object mutation elements[def.manaType].current -= drain with immutable spread pattern elements[def.manaType] = { ...elements[def.manaType], current: elements[def.manaType].current - drain }. Also added a safety check else if (elements[def.manaType]) before accessing the nested property.

Fixed: Replaced direct nested object mutation `elements[def.manaType].current -= drain` with immutable spread pattern `elements[def.manaType] = { ...elements[def.manaType], current: elements[def.manaType].current - drain }`. Also added a safety check `else if (elements[def.manaType])` before accessing the nested property.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Anexim/Mana-Loop#70