diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..9f3c10c --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,19 @@ +# AGENTS.md + +Static OBS/browser overlay that reads Beat Saber Plus Song Overlay events over WebSocket (`ws://localhost:2947/socket`). + +## Files of interest + +- [`index.html`](index.html) — Page shell: markup for map info, time bar, score, settings dialog; pulls `index.css` and `index.js`. +- [`index.js`](index.js) — Connects to BS+ WebSocket, parses JSON events (`gameState`, `mapInfo`, `pause`, `resume`, `score`), updates DOM; optional BeatSaver API fetch for custom maps; reads/writes settings from URL hash. +- [`index.css`](index.css) — Layout, theming, visibility toggles driven by body classes and CSS variables from settings. +- [`types.d.ts`](types.d.ts) — JSDoc typedefs for BS+ payloads and events (editor/IDE hints only). +- [`jsconfig.json`](jsconfig.json) — JS project roots/path so editors resolve modules and `types.d.ts`. +- [`images/`](images/) — Cover fallback (`unknown.svg`), characteristic icons under `images/characteristic/` (filenames match BS+ characteristic strings). +- [`README.md`](README.md) — User-facing usage (hosted URL, OBS, local `file://`, BS+ module). +- [`dprint.json`](dprint.json) — Formatter config for the repo. +- [`.editorconfig`](.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/JS client. diff --git a/README.md b/README.md index 3cd7fb3..bc51edc 100644 --- a/README.md +++ b/README.md @@ -7,23 +7,8 @@ Requires [BeatSaberPlus](https://github.com/hardcpp/BeatSaberPlus) ![](images/screenshots/preview.png) -## Usage +### Usage -1. Go to [bs-overlay.netlify.app](https://bs-overlay.netlify.app/) -2. Click anywhere on page to show settings (saved in URL) - ![](images/screenshots/settings.png) -3. Copy URL -4. OBS Studio: Add Source > Browser > paste URL -5. BeatSaber+ settings, enable the Song Overlay module - -### Advanced - -[Download](https://github.com/ibillingsley/BeatSaber-Overlay/archive/refs/heads/main.zip) the source code to use the overlay locally without hosting it online. +Clone the repo to use the overlay locally. Note: in OBS browser source, use URL `file:///C:/path-to-overlay.../index.html` instead of "Local file" so that URL parameters work. - -You can further customize the overlay with Custom CSS. Example: - -```css -body { font-family: "Comic Sans MS"; } -``` diff --git a/bsplus-wiki.code-workspace b/bsplus-wiki.code-workspace new file mode 100644 index 0000000..68fe382 --- /dev/null +++ b/bsplus-wiki.code-workspace @@ -0,0 +1,11 @@ +{ + "folders": [ + { + "path": "." + }, + { + "path": "../BeatSaberPlus.wiki" + } + ], + "settings": {} +} \ No newline at end of file diff --git a/docs/ADR.md b/docs/ADR.md new file mode 100644 index 0000000..f5430fd --- /dev/null +++ b/docs/ADR.md @@ -0,0 +1,17 @@ +# Architectural Decision Record + +## Static web app with typed JavaScript + +The overlay loads inside OBS from a URL or `file://` path, with no install step for streamers. + +Consequences: Ease of use + +- Adding or updating the overlay is **copy or point OBS at `index.html`** (hosted or local); nothing to build before use. +- We avoid a toolchain that would complicate “drop this folder in” or quick Netlify-style hosting. +- Type safety is **optional IDE assistance**, not enforced at publish time (there is no `tsc` in CI by default). + +This static, dependency-free shape exists **because** it stays easy to wire up as an OBS Browser Source while keeping the codebase maintainable through JSDoc and `types.d.ts`. + +## BeatSaberPlus + +Because I already use it. diff --git a/docs/testing.md b/docs/testing.md new file mode 100644 index 0000000..6c326cb --- /dev/null +++ b/docs/testing.md @@ -0,0 +1,39 @@ +# Testing in a browser + +The overlay is a static page. You can exercise the UI and wiring without OBS by opening it in any Chromium-based browser (Chrome, Edge) or Firefox. + +## Open the page + +Use a **`file://` URL** (same idea as OBS): absolute path to `index.html`, forward slashes. This clone: + +`file:///C:/Users/example/src/BeatSaber-Overlay/index.html` + +Paste that into the address bar, or drag `index.html` into a browser window. + +Settings are stored in the **URL fragment** (after `#`). Using a full `file://` URL (not only picking “Open file” in a way that strips the hash) keeps hash-based settings working, same idea as in the [README](../README.md). + +## Debug mode (no Beat Saber) + +Without the game, the overlay normally hides outside **Playing** (and during BeatSaver loading). Add a **query parameter** so it stays visible for layout or WebSocket checks: + +- Enable: `?debug=1` +- Example: `file:///C:/Users/example/src/BeatSaber-Overlay/index.html?debug=1` + +Put `?debug` **before** the `#` hash if you use both: `index.html?debug=1#…` + +## What you should see + +- The overlay layout with placeholder labels until live data arrives. +- **Developer tools → Console:** log lines such as `Connecting to ws://localhost:2947/socket` on load. If [Beat Saber Plus](https://github.com/hardcpp/BeatSaberPlus) is **not** running with the Song Overlay module listening on that port, the socket will close and the script **retries every 10 seconds**—that is expected. +- **With Beat Saber running** and BS+ Song Overlay enabled: you should see `Connection open.` when the WebSocket succeeds, and map info, time, and score update while you play. + +## Quick UI checks without the game + +- Click the page (outside the settings dialog) to toggle the **preview** / settings visibility. +- Change checkboxes and values in the dialog; the **URL hash** should update and layout should reflect toggles and scale. + +## Live data path + +End-to-end testing needs the same pieces as streaming: **Beat Saber**, **Beat Saber Plus** with the **Song Overlay** module active, so `ws://localhost:2947/socket` accepts connections. The browser page only connects to that local WebSocket; it does not start the server. + +For custom maps, the overlay may request **BeatSaver** over HTTPS; use **Network** in devtools if those requests fail (offline, blocked, or API errors). diff --git a/index.css b/index.css index 6c9310c..f8d83d2 100644 --- a/index.css +++ b/index.css @@ -41,8 +41,9 @@ body { transition-duration: calc(var(--fade, 300) * 1ms); } -body.loading, -body:not([data-game-state="Playing"], .preview) { +/* Production: hide when not Playing (or loading map meta). Debug: ?debug=1 (see index.html). */ +html:not(.debug) body.loading, +html:not(.debug) body:not([data-game-state="Playing"], .preview) { opacity: 0; } @@ -206,7 +207,8 @@ span:empty { body:not(.cover) #coverImg, body:not(.mapInfo) #mapInfo, body:not(.time) #time, -body:not(.score) #score { +body:not(.score) #score, +body:not(.bsr) #bsrKey { display: none; } diff --git a/index.html b/index.html index 7d6b7d4..1d7f4a6 100644 --- a/index.html +++ b/index.html @@ -4,6 +4,10 @@ BS Overlay +
@@ -51,6 +55,7 @@ +