4.6 KiB
Vow of Silence and Lady Anacondra — 2026-10-04
Finding
The full-fight record shows a successful Vow of Silence action against Lady Anacondra at 1791081712932, but the matching cast remained active. The cast identity is attackId: spell-9532, startedAt: 1791081712018, completesAt: 1791081713518; the action occurred 914 ms after its start with 586 ms remaining. The result records interruptObserved: false and sourceCastEndedBeforeScheduledCompletion: false. The source cast after the action still has the same ID and timestamps. Vow resolves as an Arcane, zero-amount utility event, so that event is not evidence of a damage resistance or miss.
The failure was a false source immunity. The pinned AzerothCore creature_template.sql schema stores CreatureImmunitiesId, a row reference, rather than a literal mechanic bitmask. The importer had treated that negative row ID as a mask. At runtime, applyStatus rejects Silence and Interrupt when those names appear in mob.mechanicImmunities, which prevented both Vow effects from reaching the active cast.
Source correction
The import source is AzerothCore commit 4d9d1d4b5723e819c5c390f6ca1177283dbfb8e3, recorded by azerothCoreSourceLock.json. The additional source is data/sql/base/db_world/creature_immunities.sql, SHA-256 aee81a1d8b99986f8498a2b4c51b64eaf4b9095a0d1a12bbf3705d9588a90a13 (70,706 bytes, 456 rows), preserved byte-for-byte under dungeon-pipeline/source-fixtures/azerothcore-4d9d1d4b5723e819c5c390f6ca1177283dbfb8e3/ with its lock metadata.
Lady Anacondra (template 3671) references immunity row -93. That row has SchoolMask=0 and MechanicsMask=16777248 (0x01000020); its source comment identifies Fear and Horror as mech=0x800010. The source mechanic mask uses the enum's bit positions, while the established imported/runtime template mask uses the adjacent lower positions. The importer normalizes the source mechanic mask one bit right to 0x00800010, then decodes exactly fear and horror. It imports the row's SchoolMask separately. This removes the invented Silence and Interrupt immunities without weakening any immunity declared by source. For example, row -377 explicitly lists both Silence and Interrupt and still imports both.
The importer only loads the FK table when the parsed template schema declares CreatureImmunitiesId; older schemas continue to use literal mechanic_immune_mask and spell_school_immune_mask values. A nonzero FK missing from the source table fails closed. The generated reference changes only immunity fields: 646 of 1,671 creature templates have corrected mechanic immunity fields, and 30 also receive their FK-backed school immunity fields. Other template fields and counts are unchanged.
Runtime check and limits
Vow of Silence is modeled as an 8.4-second Silence aura followed by an Interrupt effect; the player-target aura duration is 4.2 seconds. Applying Silence cancels a live nonphysical cast. Because that clears the cast before the following Interrupt effect runs, the effect sequence does not create a separate per-school lockout for the canceled Nature cast. The active Silence status itself suppresses new spell attacks during its duration. The regression therefore checks cast cancellation and the live Silence window, not a Nature school-lock timestamp.
The focused regression registers Lady through template 3671, stages the exact spell-9532 cast with its source start/completion times, verifies cancellation, and advances through the original release time while checking the cast count does not increase. Other focused cases cover a RoM physical Trample against a player target, the generated companion path against a WoW Lightning Bolt, and an NPC whose source row really grants Silence and Interrupt immunity. That immune NPC keeps its cast and receives no Silence.
This is a source/import correction and focused runtime verification. The recorded historical full fight was not replayed after the change, and this report does not claim a new browser fight result.
Validation
The focused Vitest selection passed 40/40 tests across src/game/romPriestChampionRuntime.test.ts, src/game/wailingCavernsParity.test.ts, src/game/enemyCasting.test.ts, src/game/enemyDamageTypes.integration.test.ts, and src/game/enemySmartAiRuntime.test.ts; the final revised Vow test file was rerun alone and passed 8/8. The importer regression file scripts/dungeon-pipeline/import-azerothcore-world.test.mjs passed 5/5 Node tests, and node --check scripts/dungeon-pipeline/import-azerothcore-world.mjs passed. The app TypeScript check and final build passed after the runtime-test edits. No full test suite or all-class sweep was run.