Polish finish-pass + audio crackle fixes#47
Merged
Conversation
… lifecycle/race fixes SFX bus (audio.service.ts): - Add a DynamicsCompressor limiter on the SFX master so simultaneous combat voices no longer sum past 0 dBFS and clip. - Give every tone/noise envelope a short clamped attack ramp (no onset click). - Ramp master gain on setVolume/toggleMute instead of writing .gain.value directly (no click when adjusting volume or muting mid-sound). Music bus (music.service.ts): - Bass drone now ramps in and fades out at the bar boundary instead of an instant full-gain start + immediate osc.stop (removed the per-bar click and the lookahead-scheduler early cut-off). - stopMusic() now tears down oscillator nodes (deferred on a fade), fixing zombie pads/bass that re-emerged when the next theme restored master gain. - crossfade/setMusicVolume cancelScheduledValues before restoring level so a pending stop-fade can't silence the incoming theme. - Generation-guarded deferred teardown so a fast theme round-trip can't tear down the freshly restarted theme. - tick() clamps the scheduler forward when behind (no beat burst on tab refocus). - Disconnect pluck + pad oscillators on stop; exponential pluck decay. Verified: production build + lint clean; full suite green. Manual listen pending. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…1y, balance, copy Closes the 1.0 polish punch-list from a code-grounded audit (no P0 blockers found; this addresses the confirmed P1s + the "looks-unfinished" band). Boss / arc: - Nova Sovereign shield dome re-creates after break+regen; orbiting shards animate; enrage emissive telegraph; distinct death VFX; mechanic banner subtext; per-Act-3-boss epilogue variants. WYRM_ASCENDANT gets an intro banner + eye-glow status tint. Combat / content: - Heavy Fog (ENEMY_SLOW) reworked to a fractional-movement accumulator so it affects 1-tile movers (mirrored in forward-simulation, clamped to a finite projection rate). Card description/flavor corrections (SALVAGE, CONDUIT_BRIDGE, MORTAR_BARRAGE, DETOUR); ENERGY_SURGE rarity; ARCHITECT upgrade copy. Run flow / meta: - Event-death now routes to the run summary (no more stranded empty map). - Endless mode wired as a post-victory continuation (preserves the single-run invariant). A14 event-node reduction made effective. Profile rank ceiling reachable; dead campaign achievements filtered; currency glyph in run nav; dead 'start' viewMode removed. UX / a11y: - Tower-sell feedback; hand-stuck nudge covers gold-exhausted; tutorial explains run-persistent gold; negative gold delta. body.reduce-motion applied on startup + fallbacks across reward/HUD/tutorial/act-transition/event/summary; colorblind enemy-dot shapes. Balance (conservative safety nets, unplaytested): - Minimum encounter starting-gold floor (anti-soft-lock); per-wave streak-bonus cap. Mortar placerLevel serialized; restore error-path disposes meshes. Copy / dead-UI: "Ascent Complete" → "Run Complete"; Editor nav link dev-gated; landing version string. Boss-banner flash() + ForwardSim/Profile/App specs updated to match. Full suite: 8497 passed / 0 failed / 1 skipped. Build + lint clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
resolvedCards (card-draft) and relicCards (reward-screen) were getters that allocated a fresh array of fresh objects on every access, and their *ngFor had no trackBy. Every change-detection pass therefore gave Angular all-new item identities and it rebuilt each card's DOM, replaying the entrance animation. Idle screens never re-run CD so it was invisible — but holding a key (e.g. Space on the victory screen) fires auto-repeat keydown events, one CD cycle each, producing an unbounded flicker of the reward cards. - Memoize both getters on their input array reference so they recompute only when the input actually changes (works under both template binding and the direct-set test setup, unlike ngOnChanges/ngOnInit). - Add trackBy (trackByCardId / trackByRelicId) so identity stays stable even if a new array arrives. - Specs: stable reference, recompute-on-change, trackBy keys. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes the 1.0 polish punch-list (from a code-grounded 11-dimension audit — no P0 blockers found) plus a two-pass fix of the audio crackling. Full suite: 8497 passed / 0 failed / 1 skipped. Build + lint clean.
Finish-pass (commit
f2aed6c)Boss / arc: Nova Sovereign shield dome re-creates after break+regen; orbiting shards animate; enrage emissive telegraph; distinct death VFX; banner mechanic subtext; per-Act-3-boss epilogue variants. WYRM_ASCENDANT intro banner + eye-glow tint.
Combat / content: Heavy Fog (ENEMY_SLOW) reworked to a fractional-movement accumulator so it actually affects 1-tile movers (mirrored in forward-sim, finite-clamped projection). Card copy fixes (SALVAGE / CONDUIT_BRIDGE / MORTAR_BARRAGE / DETOUR); ENERGY_SURGE rarity; ARCHITECT upgrade copy.
Run flow / meta: event-death routes to run summary (no stranded empty map); endless mode wired as a post-victory continuation (single-run invariant preserved); A14 event-node reduction made effective; profile rank ceiling reachable; dead campaign achievements filtered; currency glyph in run nav; dead
startviewMode removed.UX / a11y: tower-sell feedback; hand-stuck nudge covers gold-exhausted; tutorial explains run-persistent gold; negative gold delta;
body.reduce-motionapplied on startup + fallbacks across reward/HUD/tutorial/act-transition/event/summary; colorblind enemy-dot shapes.Balance (conservative, unplaytested): minimum encounter starting-gold floor (anti-soft-lock); per-wave streak-bonus cap. Mortar
placerLevelserialized; restore error-path disposes meshes.Copy / dead-UI: "Ascent Complete" → "Run Complete"; Editor nav link dev-gated; landing version string.
Audio crackle fixes (commit
0cc017b)SFX bus: master limiter (no combat clipping); click-free attack envelopes; ramped volume/mute (no zipper click).
Music bus: bass attack + bar-aligned release (per-bar click gone);
stopMusic()now stops oscillator nodes (fixes zombie pads/bass re-emerging under the next theme);cancelScheduledValueson crossfade/volume restore; generation-guarded teardown; background-tab scheduler clamp (no beat burst on refocus); oscillator-disconnect leak fixes; exponential pluck decay.Deliberately not done (flagged, not bugs)
padGain) → compressor pumps on crossfade. "Fixing" it makes the music quieter than tuned — a mix call for a human ear, left alone.fadePadOutanchor finding — real in theory, inert at the shipped 70–110 BPM tempos; skipped to avoid a riskiercancelScheduledValueschange.🤖 Generated with Claude Code