2.6 KiB
2.6 KiB
AGENTS.md
OBS/browser overlay that reads Beat Saber Plus Song Overlay events over WebSocket (ws://localhost:2947/socket). Serve the folder with deno task serve (see src/server/serve.ts) so the request-queue JSON loads from the same origin; configure overlay.toml (BS+ Database.json path, BeatLeader id, and optional UI defaults).
Files of interest
index.html— Page shell: markup for map info, time bar, score, settings dialog; pullsindex.cssand bundledindex.jsmodule.src/client/index.ts— Main overlay source in TypeScript; connects to BS+ WebSocket, parses events (gameState,mapInfo,pause,resume,score), updates DOM, and manages settings/hash state.src/client/types.ts— Shared TypeScript types for BS+ payloads/events and chat request JSON.index.js— Bundled browser output generated fromsrc/client/index.tsviadeno task build.index.css— Layout, theming, visibility toggles driven by body classes and CSS variables from settings.src/server/serve.ts— Deno static server; readsoverlay.tomland mapsChatRequest.jsonto BS+Database.json; serves/api/overlay-config(defaultsJSON for the overlay UI and BeatLeader id).src/client/overlay-config.ts— TOML field mapping and merging/api/overlay-configinto page defaults.deno.json— Deno tasks and TypeScript compiler options (build,serve,dev).images/— Cover fallback (unknown.svg), characteristic icons underimages/characteristic/(filenames match BS+ characteristic strings).README.md— User-facing usage (Deno, OBS URL, BS+ module).dprint.json— Formatter config for the repo..editorconfig— Basic indent/charset rules for editors.
Out of scope here
Beat Saber Plus itself (game mod) exposes the socket; this repo is only the HTML/CSS/TS client.
Implementation notes
- Live API calls are proxied same-origin via
src/server/serve.ts:/api/beatleader?path=/...,/api/beatsaver?path=/...(CORS). - Map correlation is hash-based: resolve BeatSaver map/hash first, then BeatLeader leaderboards via
/leaderboards/hash/{hash}. - Friend scores use
/leaderboard/{leaderboardId}for stableplayerIdfields. - Mutual friends: intersection of
/player/{id}/followers?type=Followingandtype=Followers(paged bypage+count). #friendScores: best accuracy per friend for the current map, sorted descending.