Files
LlamaCasty/TASKS/task-11-polish-batch.md
gramps 87509bcf99 docs: restructure TASKS.md into a catalog — one file per task in TASKS/
TASKS.md is now the index (status table, open items, research pointer).
33 files: 32 task files + 1 research facts file. The full take-saga
narrative and all design decisions are preserved verbatim; the catalog
makes the queue readable without opening every task body. Schema and
AGENTS.md updated to reflect the new layout.
2026-09-05 16:31:46 -07:00

3.3 KiB

TASK 11 — Post-pause polish batch: the creator's 8 review issues (2026-08-15, shipped)

Catalog: TASKS.md — status and requirements live here.

Status: ✅ SHIPPED 2026-08-15 — 197 tests passing, 0 warnings (ONE integration test: AudioPipelineTests.Mix_HonorsProviderGains_AndGameMute_KillsTheLoopback).

The creator reviewed the TASK 8 build and filed 8 issues. All fixed in one branch on main:

  1. ✅ Desktop/game audio volume slider had no effect (headset OR stream) — the AudioMixer's micGain/loopbackGain seams defaulted to unity because the VM never passed them; the sliders were decorative. Fixed: new AudioGainProvider (Services/Audio/) hands MicMuted/MicVolume/ GameMuted/GameAudioVolume to the mixer at construction, read live each mix tick.
  2. ✅ Desktop/game mute button had no effect — same root cause; GameMuted now zeroes the loopback on the stream. Locally, MusicPlayer.LocalGain (new) is scaled by the game bar on every volume/mute change + on TRAX load, so the creator hears the control work on the music (the track rides the loopback channel, so it ducks locally exactly as it does on stream).
  3. ✅ TRAX played once then stopped — MusicPlayer.OnPlaybackStopped only looped when Position >= Length, unreliable for MediaFoundationReader; now any clean stop (e.Exception == null) rewinds + replays; only errors/explicit stops surface via PlaybackEnded.
  4. ✅ TRAX/MIC buttons swapped — TRAX no longer sits between MIC and the (mic-specific) meter; the footer's mic cluster is MIC + meter + mute + volume.
  5. ✅ Mic source persists across restarts — LayoutStore gained a Settings key/value table (SaveMicSourceName/LoadMicSourceName); the VM saves on pick and restores before the mixer's first Start, so a restart reconnects the same already-vetted device (green dot) or reports it missing (yellow) instead of falling back to the default endpoint.
  6. ✅ TRAX moved into the game audio bar — left of the "Desktop Audio" label in the preview overlay (the creator's follow-up pick), no longer in the footer; its tooltip teaches the clicks ("left-click pauses/plays, right-click chooses a track").
  7. ✅ Backdrop's icons shifted right — the trash button's Collapsed released its column; a new HiddenBoolToVisibilityConverter keeps the slot reserved (Hidden), so edit/eye stay in their fixed columns for every source row.
  8. ✅ No separation between scenes and sources — a 1px hairline with top/bottom padding now sits between the two listboxes in the left panel.

Design decisions

  1. The gain seams are the one source of truth — AudioGainProvider is a thin seam (four Funcs) so the mixer contract and the mute⇔zero-volume rule are testable without constructing the VM.
  2. Stream-honest AND locally audible — the game bar's controls now do two things: scale the loopback on the stream and scale the music in the headphones. Native game audio is untouched (system output, OBS-style non-monitored); an OBS-style monitor loop is out of scope.
  3. Persist the DisplayName, not the device ID — the FriendlyName match was already the mic's identity end-to-end; Settings just makes it survive restarts.