[priority: 5] Special effects (Executioner/Berserker) completely broken — hasSpecial({}) always false #68

Closed
opened 2026-05-19 09:08:36 +02:00 by Anexim · 1 comment
Owner

Severity: 5 — Critical
File: src/lib/game/stores/gameStore.ts, lines ~222-228

Description:
In the tick() method's combat onDamageDealt callback, hasSpecial is called with an empty object {}:

if (hasSpecial({}, SPECIAL_EFFECTS.EXECUTIONER) && ...)
if (hasSpecial({}, SPECIAL_EFFECTS.BERSERKER) && ...)

The hasSpecial function checks effects?.specials?.has(specialId). Since {} has no specials property, this always returns false. The Executioner (+100% damage to low-HP enemies) and Berserker (+50% damage when low mana) special effects are completely non-functional.

Fix: Compute actual effects at the top of tick() and pass them to hasSpecial:

const effects = getUnifiedEffects(state);
// ...
if (hasSpecial(effects, SPECIAL_EFFECTS.EXECUTIONER) && ...)
**Severity:** 5 — Critical **File:** `src/lib/game/stores/gameStore.ts`, lines ~222-228 **Description:** In the `tick()` method's combat `onDamageDealt` callback, `hasSpecial` is called with an empty object `{}`: ```ts if (hasSpecial({}, SPECIAL_EFFECTS.EXECUTIONER) && ...) if (hasSpecial({}, SPECIAL_EFFECTS.BERSERKER) && ...) ``` The `hasSpecial` function checks `effects?.specials?.has(specialId)`. Since `{}` has no `specials` property, this always returns `false`. The Executioner (+100% damage to low-HP enemies) and Berserker (+50% damage when low mana) special effects are **completely non-functional**. **Fix:** Compute actual effects at the top of `tick()` and pass them to `hasSpecial`: ```ts const effects = getUnifiedEffects(state); // ... if (hasSpecial(effects, SPECIAL_EFFECTS.EXECUTIONER) && ...) ```
Anexim added the ai:todo label 2026-05-19 09:08:36 +02:00
n8n-gitea was assigned by Anexim 2026-05-19 09:08:36 +02:00
Anexim added the ai:done label 2026-05-19 12:38:53 +02:00
Author
Owner

Fixed. In gameStore.ts tick(), replaced hasSpecial({}, ...) with real effect computation:

  1. Import computeEquipmentEffects from effects and computeDisciplineEffects from effects/discipline-effects
  2. Import useCraftingStore and useDisciplineStore
  3. At top of tick(), compute equipment specials from enchanted gear and discipline specials from active discipline perks
  4. Merge into a single Set<string> and pass to hasSpecial(effects, ...)

Executioner (+100% damage to low-HP enemies) and Berserker (+50% damage when low mana) now correctly trigger when the player has the corresponding enchantment or discipline perk.

Also fixed pre-existing typo: attunementattunements in computeRegen call.

TypeScript compiles clean for gameStore.ts. All 60 existing tests still pass.

✅ Fixed. In `gameStore.ts` tick(), replaced `hasSpecial({}, ...)` with real effect computation: 1. Import `computeEquipmentEffects` from `effects` and `computeDisciplineEffects` from `effects/discipline-effects` 2. Import `useCraftingStore` and `useDisciplineStore` 3. At top of tick(), compute equipment specials from enchanted gear and discipline specials from active discipline perks 4. Merge into a single `Set<string>` and pass to `hasSpecial(effects, ...)` Executioner (+100% damage to low-HP enemies) and Berserker (+50% damage when low mana) now correctly trigger when the player has the corresponding enchantment or discipline perk. Also fixed pre-existing typo: `attunement` → `attunements` in computeRegen call. TypeScript compiles clean for gameStore.ts. All 60 existing tests still pass.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Anexim/Mana-Loop#68