Files
Vocaluxe/AGENTS.md
T

4.8 KiB

Vocaluxe (fork at git.disi.dev/Projects/Vocaluxe)

Fork of Vocaluxe/Vocaluxe, a karaoke game (C#, .NET 10). Default branch develop tracks upstream; the fork's own work happens on feature branches. Keep changes to upstream code small and hook-based, so upstream can still be merged.

Goal of the fork

  1. Song server (VocaluxeSongServer/, in progress): a central song library on the homelab. The game becomes the frontend and downloads song files on demand. See VocaluxeSongServer/README.md.
  2. Later: serve the guest WebApp ("browse by phone", WebApp/ + VocaluxeWeb/) directly from the server.
  3. Search and download songs that aren't in the library (started: server web UI with the sources free and usdb; next: more sources, UltraSinger to create songs from audio).

Layout

Folder What
Vocaluxe/ The game. Song server client: Base/SongServer/ (CSongServer sync, CRemoteSongFileProvider downloads)
VocaluxeLib/ Shared library. Songs/CSongFiles.cs is the hook every song file access goes through
VocaluxeSongServer/ ASP.NET Core server, Docker image git.disi.dev/projects/vocaluxe-song-server. Sources/: song search and downloads (free CC songs from GitHub, USDB + yt-dlp). wwwroot/: mobile web UI (plain JS, no build)
VocaluxeWeb/, WebApp/ Built-in webserver of the game and the guest WebApp (Vue), upstream
Tests/ NUnit; song server tests in Tests/SongServer

How the song server integration works

  • CSongs.LoadSongs calls CSongServer.Sync(): fetches /api/v1/library (ETag), mirrors the song .txt files into <DataFolder>/SongServer/<host>_<port> (zip bundles), deletes files no longer on the server, and installs CRemoteSongFileProvider as CSongFiles.Provider. The cache folder is then loaded like a normal song folder.
  • CSongFiles.Exists (loader header checks) is true for files that only exist on the server. IsLocal means the file is downloaded and current (size and mtime match the server).
  • Downloads on demand: covers (CSong.LoadSmallCover, background threads, blocking), preview audio (CBackgroundMusic.LoadPreview + Update), everything before singing (CScreenSing._LoadAndStartCurrentSong, progress via TR_SCREENSING_DOWNLOADING). Downloads resume from .part files with Range requests.
  • Config: config.xml section SongServer (Url, ApiKey). The contracts (VocaluxeSongServer/Contracts) are linked into Vocaluxe.csproj; the test project references the server with extern alias songserver.

Song server web UI and sources

  • The web UI is plain HTML/CSS/JS in VocaluxeSongServer/wwwroot (no build step, no external requests except cover images). Check it at phone width: headless Edge has a ~500px minimum window, so render the page in a 390px iframe.
  • USDB can't be tested without an account (search and text download need a login). Its HTML parsing is covered by Tests/SongServer/CSongSourcesTest.cs; if USDB changes its HTML, fix CUsdbSongSource.ParseList there.

Build and test (Windows)

  • dotnet build Vocaluxe/Vocaluxe.csproj -c DebugWin -p:Platform=x64 (the whole solution also builds the native PitchTracker, which needs Visual Studio's C++ tools).
  • dotnet test Tests/Tests.csproj -c DebugWin -p:Platform=x64
  • Running the game (Output\Vocaluxe.exe) without the C++ tools: take libs/unmanaged/x64/PitchTracker.dll (and the Themes/Vocaluxe 2024/*.mp4 videos) from the upstream Nightly zip (github.com/Vocaluxe/Vocaluxe/releases/tag/Nightly, Vocaluxe_Nightly_Windows_x64.zip); the PitchTracker source is unchanged in this fork. Both are gitignored. Data and Config.xml are in Output (non-installer builds).
  • First start is slow on Windows with Smart App Control: GStreamer (default PlayBackLib) scans its 216 plugins once and each unsigned DLL is checked (~19 min on DisiFramework, window "not responding" in "Init Playback"). Later starts are fast. <Sound><PlayBackLib>PortAudio</PlayBackLib></Sound> in Config.xml avoids GStreamer.
  • Building rewrites the copyright year in Vocaluxe/Properties/AssemblyInfo.cs; don't commit that.
  • Don't use dotnet sln add: it rewrites the configuration table of Vocaluxe.sln. Copy the lines of VocaluxeWeb.
  • New config.xml fields must also go into Tests/VocaluxeLib/XML/TestFiles/SConfig.xml (round-trip test; CRLF).

Known gaps (song server)

  • Cover/background auto-detection ([CO]/[BG] files without a tag, CSong._CheckFiles) only sees local files.
  • Media in subfolders of a song folder are not served (only the song folder itself).
  • On Linux clients, media whose name differs in case from the .txt reference won't be found after download.
  • No cache size limit yet. The WebApp's cover images for server songs depend on the cover loader having fetched them.
  • No in-game UI for the server address yet (only config.xml).