Add documentation, a debug mode, and minor changes to defaults
This commit is contained in:
parent
bf4aa27ca3
commit
f8b6c06f89
19
AGENTS.md
Normal file
19
AGENTS.md
Normal file
@ -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.
|
||||
19
README.md
19
README.md
@ -7,23 +7,8 @@ Requires [BeatSaberPlus](https://github.com/hardcpp/BeatSaberPlus)
|
||||
|
||||

|
||||
|
||||
## 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)
|
||||

|
||||
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"; }
|
||||
```
|
||||
|
||||
11
bsplus-wiki.code-workspace
Normal file
11
bsplus-wiki.code-workspace
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"folders": [
|
||||
{
|
||||
"path": "."
|
||||
},
|
||||
{
|
||||
"path": "../BeatSaberPlus.wiki"
|
||||
}
|
||||
],
|
||||
"settings": {}
|
||||
}
|
||||
17
docs/ADR.md
Normal file
17
docs/ADR.md
Normal file
@ -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.
|
||||
39
docs/testing.md
Normal file
39
docs/testing.md
Normal file
@ -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).
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -4,6 +4,10 @@
|
||||
<meta charset="utf-8">
|
||||
<title>BS Overlay</title>
|
||||
<link rel="stylesheet" href="index.css">
|
||||
<script>
|
||||
if (new URLSearchParams(location.search).get("debug") === "1")
|
||||
document.documentElement.classList.add("debug");
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="row">
|
||||
@ -51,6 +55,7 @@
|
||||
<label>Show map info: <input id="mapInfoInput" type="checkbox"></label>
|
||||
<label>Show time: <input id="timeInput" type="checkbox"></label>
|
||||
<label>Show score: <input id="scoreInput" type="checkbox"></label>
|
||||
<label>Show BSR / map id: <input id="bsrInput" type="checkbox"></label>
|
||||
<label>Position: <select id="positionInput">
|
||||
<option value="[false,false]">Top left</option>
|
||||
<option value="[true,false]">Top right</option>
|
||||
|
||||
5
index.js
5
index.js
@ -171,8 +171,9 @@ const settings = {
|
||||
mapInfo: true,
|
||||
time: true,
|
||||
score: true,
|
||||
bsr: false,
|
||||
right: false,
|
||||
bottom: false,
|
||||
bottom: true,
|
||||
scale: 1,
|
||||
fade: 300,
|
||||
};
|
||||
@ -205,7 +206,7 @@ document.head.appendChild(style);
|
||||
|
||||
// Settings UI
|
||||
|
||||
for (const key of ["cover", "mapInfo", "time", "score"]) {
|
||||
for (const key of ["cover", "mapInfo", "time", "score", "bsr"]) {
|
||||
const input = document.getElementById(`${key}Input`);
|
||||
input.checked = settings[key];
|
||||
input.oninput = () => {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user