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; pulls index.css and bundled index.js module.
  • 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 from src/client/index.ts via deno task build.
  • index.css — Layout, theming, visibility toggles driven by body classes and CSS variables from settings.
  • src/server/serve.ts — Deno static server; reads overlay.toml and maps ChatRequest.json to BS+ Database.json; serves /api/overlay-config (defaults JSON for the overlay UI and BeatLeader id).
  • src/client/overlay-config.ts — TOML field mapping and merging /api/overlay-config into page defaults.
  • deno.json — Deno tasks and TypeScript compiler options (build, serve, dev).
  • images/ — Cover fallback (unknown.svg), characteristic icons under images/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 stable playerId fields.
  • Mutual friends: intersection of /player/{id}/followers?type=Following and type=Followers (paged by page + count).
  • #friendScores: best accuracy per friend for the current map, sorted descending.