May 10, 2026 (night)
- Fix 跳樓機 + 開始懂了 — negative lyricTimes corrected — both songs had production credits embedded in their LRC files in non-standard format (吉他:, 词:) bypassing the credit filter. batch_char_align ran against the wrong reference timing, producing lyricTimes starting at −2 s and −11 s. Fixed by cleaning LRC files, re-running auto_offset against R2 audio (offsets +4.17 s / +5.49 s), and re-running char_align. 开始懂了: 51 lines, 331 chars, 1 fallback; 跳樓機: 53 lines, 468 chars, 0 fallbacks
- Fix Countdown timer aligned to lyrics for all 36 songs — 24 songs had firstVocalSec set too early or late vs the actual lyricTimes[0]. Batch-updated all to firstVocalSec = max(0, lyricTimes[0]−6) so the countdown fires exactly 6 s before the first highlighted character. Biggest fixes: 七里香 16→34, 戒煙 21→7, 忘記擁抱 25→11, Make You Feel My Love 26→12, 身後 19→25
May 10, 2026 (evening)
- Fix 我對緣分小心翼翼 (JJ Lin) — lyrics & WhisperX alignment completed — last song missing char-level timing. No LRC existed anywhere; sourced lyrics from NetEase Music API, converted Simplified→Traditional (OpenCC), verified offset +0.19 s vs R2 audio (confidence 0.97). char_align: 31 lines, 358 chars, 0 fallbacks. firstVocalSec updated to 28 s. All 36 songs now have per-character timestamps
May 10, 2026 (continued)
- Fix WhisperX char alignment deployed — all 36 songs — per-character timestamps now live in production. 35/36 songs upgraded (xiao-xin-yi-yi skipped: no LRC available). Average coverage 97–100% per line; 0 fallbacks on most songs
- Fix 丟了你 (井朧) timing corrected — the original /tmp audio was a truncated 65 s clip from a different YouTube source, causing lyricTimes to be calibrated 12 s late. Replaced with the full R2 audio (272 s), re-detected offset +0.25 s, re-ran char_align. Song now in sync
- Fix batch_char_align.py stray-stdout fix — a transformers model-load log line (datetime-prefixed) was printing to stdout before the JSON output, causing json.parse to fail on 4 songs. Fixed by stripping everything before the first '{' before parsing
- Feature Song of the Day — deterministic daily featured song (purple card at top of All filter). Seed: year×10000 + month×100 + day mod library length. No manual curation needed
- Feature Language filter — 中文 / English / difficulty pill filters on song list. Chinese detection via Unicode CJK range, no songs.js changes needed
- Feature Continue shortcut — home screen shows last-played song as a quick-resume button. Persisted in localStorage stats.lastSong
May 10, 2026
- Feature Timed lyrics display — synchronized karaoke wipe with per-character highlighting. Characters light up as you sing them: past chars turn accent-purple with glow, the active char pulses, upcoming lines are faded. Color shifts to green when pitching well, red when off — visual accuracy feedback at the character level
- Feature Pitch direction indicator — real-time ↑/↓/✓ arrow (right edge of canvas) showing whether your current pitch is too high, too low, or on target vs the melody segment. Folds to nearest octave so it reads correctly regardless of register
- Feature Grade bombs + combo system — line-completion triggers a score bomb (PERFECT / GREAT / GOOD / MISS) with a punch animation. Consecutive good lines build a combo counter (levels 0–3) that shifts the trail color from cyan → green/gold → gold/orange → purple/hot-orange and adds a glow border to the lyrics bar
- Feature Varied feedback messages — pool of 30+ contextual compliments (mixed English/Chinese) for perfect hits, good hits, 5/10/20 streaks, drawn at random so they never feel repetitive
- Fix Auto-calibrated LRC timing for all 36 songs — WhisperX forced alignment on a ±15 s audio slice around the first lyric automatically detects how far off the LRC timestamps are from the actual video file. 26 songs had significant drift; largest corrections: Espresso +13.4 s, 節煙 +12.9 s, 丟了你 −12 s, 可在我心底的名字 −11.7 s, 深喉 +12 s. All corrections high confidence (score ≥ 0.84)
- Fix Video layer stripped from lyrics-mode songs — lyricsMode songs no longer load or display the MV video background. The full canvas shows the pitch visualizer instead; game clock uses the Web Audio clock directly (more accurate). Saves ~23 MB bandwidth per play
- Feature 七里香 (Jay Chou) lyrics added — fetched synced LRC, detected −11.56 s offset, corrected. firstVocalSec now 16 s
- Feature Per-character WhisperX alignment — replacing linear interpolation within lyric lines with actual forced alignment timestamps so each character lights up precisely when sung. Running overnight across all 36 songs
Apr 30, 2026 (evening)
- Feature Added 3 new songs: 倒帶 (蔡依林 Jolin Tsai), 至少還有你 (林憶蓮 Sandy Lam), 跳樓機 (LBI 利比) — all karaoke-source videos, no Demucs needed
- Fix Countdown invisible on MV songs (一念, 至少還有你, etc.): browser composites
<video> elements in their own layer above positioned overlays regardless of z-index. Fixed by giving #game-mv explicit position: relative; z-index: 1 so the compositor correctly layers it below the countdown (z-index 30) and grade-bomb (z-index 60). All 32 songs confirmed to have a countdown source
- Fix Karaoke toggle still visible on songs with no vocal stem: CSS
display: inline-flex on .btn-karaoke-mid was overriding the HTML [hidden] attribute. Added display: none !important rule — toggle now correctly hidden for all stripVocals: false songs
- Feature In-game feedback & bug reporting system: floating "Feedback" pill (bottom-right) opens a compact modal with Bug / Idea / Timing report types. Auto-attaches game context (song, timestamp, score, streak, karaoke state, browser). Reports write to
public.feedback in Supabase with RLS — anonymous INSERT only, authenticated read
- Feature Triage keyword: say triage to trigger automatic feedback review — Claude queries unresolved reports, fixes what it can (timing adjustments, bugs), marks them resolved in Supabase, and deploys
Apr 30, 2026
- Fix Ambient noise scoring 100 without singing: all lyric notes have midi=0 (presence-only mode), so the confidence gate of 0.15 let room noise score freely. Raised presence-only gate to 0.6 — real singing voice produces a clean fundamental well above this; ambient hum does not
- Fix RANK and SCORE HUD blocks visible at game start showing "#—" and "0": CSS
display: flex was overriding the HTML [hidden] attribute. Added display: none !important rule for both blocks; also cleared "#—" placeholder from rank HTML so any flash shows nothing
- Fix SCORE now hides until user starts singing — score block only appears once liveScore > 0, driven by actual voiced frames, not a floor constant
- Fix Countdown fires too late / after user needed to start singing: extended warning window from 3.5 s → 5.5 s (now shows 5-4-3-2-1-GO!). Added explicit
firstVocalSec to all 32 songs pulled from actual lyric JSON first-note timestamps — countdown now always fires at the right moment regardless of JSON loading order
- Fix Make You Feel My Love and 身騎白馬 countdown fired at 3 s (wrong): emptied their lyric JSON files so MV global-frame scoring applies;
firstVocalSec (14 s and 18 s) drives the countdown instead
- Fix MV songs (empty notes) showed live score "—" throughout:
_computeLiveScore() now returns a presence-based score once voiced frames accumulate, so the score builds live as you sing
- Fix Karaoke toggle audit: 6 songs downloaded from karaoke/instrumental YouTube sources have
instrumentalSrc === audioSrc — toggling did nothing. Set stripVocals: false to hide the toggle for bu-neng-shuo, perfect, love-story, beautiful-things, espresso, make-you-feel-my-love
- Fix Key metadata corrected (verified via Tunebat/SongBPM): Espresso E Major → A Minor; Beautiful Things C Major → Bb Major; 七里香 F Major → C Minor; 愛的就是你 G Major → F Major
- Feature Added 2 new songs: 身騎白馬 (徐佳瑩 Lala Hsu) and Make You Feel My Love (Adele) — full MV pipeline with Demucs vocal separation on 身騎白馬
- Feature Pre-deploy checklist added (
DEPLOY_CHECKLIST.md): covers scoring logic, CSS hidden states, countdown timing, karaoke toggle correctness, new song requirements, and HUD behaviour — run before every production deploy
Apr 29, 2026
- Feature KTV MV mode: all 30 songs now have full music video playback. During a song, the original KTV video plays with burned-in lyrics; Demucs vocal separation provides a clean instrumental track for karaoke mode
- Feature MV video layout: video centred and constrained (max 720px, 90% width, rounded corners) rather than full-bleed, giving a cleaner KTV-booth feel
- Fix Karaoke-source songs (Perfect, Love Story, Beautiful Things, Espresso, 不能說的秘密) correctly reuse the audio file as the instrumental track — no Demucs pass needed since the source already has no lead vocals
- Fix All media served from Cloudflare R2 via Vercel /media/ proxy rewrite, eliminating CORS issues
- Fix Entire song card is now clickable — onclick moved from inner content div to the outer card wrapper; karaoke toggle retains stopPropagation so it doesn't accidentally launch the song
Apr 27, 2026
- Fix Silent backing track on second song: AudioContext auto-suspends after ~30 s of silence between songs. The unlock handler was one-shot and wouldn't revive it. Now re-fires on every user gesture; also resumes the context synchronously at the top of song selection, before the countdown breaks the gesture chain
- Fix Score of 100 possible with karaoke off: presence-only formula (coverage × 85%) could max at 100, making "sang the whole song" look like a perfect score. Original audio mode now has its own capped formula (max 75) so the result honestly reflects that pitch wasn't graded
- Feature Original audio warning modal: switching a song from Karaoke Mode to original audio now shows a blocking confirmation — "Rankings won't count" — before the change applies. Primary action is "Keep Karaoke Mode" so the default path stays accurate
Apr 23, 2026
- Fix Blank screen for first 5 seconds of every song: browser autoGainControl ramps mic gain unpredictably for ~5 s after open, causing YIN confidence to stay low and trail/scoring gates to block all input. Disabled AGC; lowered noise floor threshold to compensate so quiet singers still register
- Fix Pitch trail and scoring confidence gates lowered (0.35→0.15 and 0.30→0.15): the first frames of each phrase warm up slower than steady-state singing — the old thresholds were eating the opening of every line
- Fix Systematic scoring collapse (users seeing 7% pitch accuracy): the volume gate was accumulating samples even when it forced accuracy to zero — poisoning the average across the whole song. Replaced volume gate with a YIN confidence gate that returns early, so only real-voice frames count toward accuracy
- Fix 胆小鬼 (Gigi Leung): two lyric windows were spanning instrumental bridges (one 29 s, one 9 s) — singers were scored absent for almost the entire bridge even when humming. Trimmed to actual sung duration
- Fix Pitch trail appearing during silence and on instrumental bleed: added midi≤0 guard to both trail renderers, and confidence gate on trail history push to reject mixed-harmonic noise from the backing track
Apr 20, 2026
- Feature Personalised greeting on home screen for signed-in users: "Welcome back, [name]" on return visits
- Feature Returning users see a "What's new" devlog link instead of the Loom walkthrough video
- Feature Pinyin / romanisation search: typing hanyu pinyin (e.g. "gu dan bei ban qiu") in the search bar now matches Chinese song titles
- Fix Second song had no sound: AudioContext was suspended after the first song ended; now resumed at the start of each new song
- Fix Singing on mobile with karaoke off caused the music to duck: browser acoustic echo cancellation was treating the backing track as feedback and suppressing it. All audio processing constraints (echoCancellation, noiseSuppression, autoGainControl) are now disabled on the mic input
Apr 19, 2026
- Infra songs.js split into per-song data files: initial JS payload drops from 763 KB to 17 KB. Song notes and melody now load on demand when you tap a song.
- Feature Search bar on song select: real-time filter by title or artist, composes with difficulty tabs
- Fix Pitch trail renderer: batch-evict stale history entries in one call instead of per-frame loop at 60 fps
Apr 18, 2026
- Song Added 胆小鬼 (梁咏琪 Gigi Leung): G Major, 522-note melody, 74 user-synced lyric lines
- Song Added P.S. 我愛你 (A-Lin 黃麗玲): Ab Major, 598-note melody, 39 user-synced lyric lines
- Song Added 忘記擁抱 (A-Lin 黃麗玲): E Major, 642-note melody, 33 user-synced lyric lines
- Song Added 刻在我心底的名字 (盧廣仲 Crowd Lu): F Major, 734-note melody, 42 user-synced lyric lines
- Song Added 幾分之幾 (盧廣仲 Crowd Lu): Db Major, 529-note melody, 24 user-synced lyric lines
- Feature Profile page: song bests, stats overview, Sing-Off history. Access via profile menu → View Profile
- Fix Song grid crash when a song had empty notes array; getDuration now guards against it
Apr 17, 2026 (night)
- Song Added 愛,請問怎麼走 (A-Lin 黃麗玲): F Major, 775-note melody, 33 user-synced lyric lines
- Song Added 有一種悲傷 (孫燕姿 Stefanie Sun): E Minor, 441-note melody, 22 user-synced lyric lines
- Song Added 雨蝶 (李翊君): Bb Minor, 534-note melody, 72 user-synced lyric lines
Apr 17, 2026 (evening)
- Song Added 一念 (張紫寧 & 李鑫一): 逐玉 OST, 405-note melody, 37 user-synced lyric lines
- Song Added 我对缘分小心翼翼 (林俊傑 JJ Lin): 逐玉 OST, 673-note melody, 36 user-synced lyric lines
Apr 17, 2026
- Feature Sing-Off: async PvP challenges. Finish a song, tap "Challenge a Friend", share the link. When a friend accepts and plays the same song, both sides see a VS arena with scores, grades, and a winner crown. Public read, auth-only write, short unguessable IDs.
- Fix Results screen no longer hangs on slow networks. All Supabase calls in the end-of-game path (settle, leaderboard, challenge create) now have a 10-second timeout so a hung request can never freeze the game screen.
- Feature Leaderboard paints instantly on repeat visits via a 5-minute localStorage cache. Transient timeouts no longer blank the list if cached data exists.
- Feature Song load is faster on karaoke tracks: vocal and instrumental MP3s now fetch in parallel instead of serially.
Apr 16, 2026 (evening)
- Fix 普通朋友 chorus pitch bars now render at the correct octave (was octave-low on "I only wanna be your friend" because pYIN tracked the harmony stack)
- Feature In-line octave smoother: any song's syllable bar that's an octave off vs the line median gets snapped back automatically, so harmony-heavy tracks no longer mislead singers
- Fix Leaderboard no longer hangs forever on flaky network. 10-second timeout with a "Tap to retry" button when the request stalls.
Apr 16, 2026
- Fix Scoring overhaul: per-syllable quantized target pitch. Held notes no longer penalized by pYIN contour wiggle. Perfect singer now scores 100% (was 42–79% depending on song).
- Feature Live 0–100 score in the HUD: mirrors the final results formula, so mid-song grade matches end-screen grade
- Feature Color-coded active lyric: current line turns green / yellow / red over a rolling 1s accuracy window, giving instant on/off-track feedback
- Song Added Love Story (Taylor Swift): 496-note melody extracted via Demucs + pYIN
- Song Added 普通朋友 (陶喆 David Tao): 720-note melody, Chinese R&B classic
- Infra Vercel Web Analytics enabled
Apr 14, 2026 (evening)
- Song Added 绿光 (孙燕姿): bilingual Chinese/English lyrics with manual timing sync
- Song Added I Don't Wanna Wait (David Guetta & OneRepublic): full lyrics with timing sync
- Song Added 起风了 (买辣椒也用券): Chinese lyrics with pinyin, manual timing sync
- Feature Loom walkthrough video embedded on homepage for new users
- Fix Share card now correctly passes score data to renderer
Apr 14, 2026
- Feature Share your score after each song with a copyable visual card
- Feature On-demand audio loading: songs load when you tap, not all at once
- Fix Mobile page crash on Safari/incognito caused by 140MB bulk audio preload
- Fix Song cards collapsed on mobile: missing artist, tags, karaoke badges
- Fix Ghost scoring: instrumental bleed through mic no longer gives false points
- Fix Canvas scaling compounded on phone rotation, breaking game visuals
- Fix Songs that hadn't finished loading would start with no audio
Apr 13, 2026
- Feature Karaoke mode (instrumental tracks) now available for all songs
- Fix Mobile responsiveness overhaul: single-column grid, proper text wrapping, touch-friendly targets
- Infra Custom domain live: vocalstar.lol
- Infra Supabase backend: auth, leaderboard, session tracking
Apr 12, 2026
- Feature User auth with email/password sign-up and sign-in
- Feature Profile customization: display name, avatar upload, color themes
- Feature Leaderboard with per-song and global rankings
- Feature Daily session limit (20 sessions) to manage server costs
- Feature Scoring methodology section explaining how pitch grading works
Apr 10–11, 2026
- Feature Real-time pitch detection via Web Audio API + autocorrelation
- Feature pYIN melody extraction pipeline for vocal pitch reference
- Feature Lyrics mode: synced Chinese lyrics with karaoke highlighting
- Feature Countdown screen with 3-2-1 animation before each song
- Feature Results screen with score circle, pitch accuracy breakdown