# Beat Saber Smoketest Workflow Use this workflow after installing or removing a plugin batch. It is adapted from the Setlist repo's working Proton/BSManager smoketest notes. The routine smoketest should be short: about 20 seconds wall time for launch, menu/UI initialization, and log check, followed by immediate teardown. If expected plugin log lines do not appear inside that window, treat that as a failure to investigate instead of repeatedly stretching the timeout. ## Preconditions - Run from the target BSManager instance directory, for example: ```sh cd "$HOME/.local/share/BSManager/BSInstances/1.44.1" ``` - The instance should contain BSIPA (`IPA/`, `IPA.exe`, `winhttp.dll`, and `Plugins/`). - If those files are absent, the run can still produce Unity `Player.log` output, but it will not produce `Logs/_latest.log` or any IPA plugin-loading evidence. Run `plugin-helper bootstrap --instance ` before using this workflow to validate plugins. - On Plasma + Wayland, the shell needs working desktop session variables: `DISPLAY`, `WAYLAND_DISPLAY`, and `XDG_RUNTIME_DIR`. If the IDE terminal is missing them, copy values from the logged-in desktop session. ## Launch Run the Proton launch in the foreground with a short watchdog. Backgrounding the Proton launch itself from an IDE terminal has been observed to exit early before Beat Saber writes useful `_latest.log` lines. Important: `timeout` may stop the launcher wrapper without killing the full Beat Saber/Proton process tree. Prefer a watchdog that sleeps for the smoke window and then kills the game process by name. ```sh export SteamAppId=620980 SteamOverlayGameId=620980 SteamGameId=620980 export WINEDLLOVERRIDES='winhttp=n,b' export STEAM_COMPAT_DATA_PATH="$HOME/.local/share/BSManager/SharedContent/compatdata" export STEAM_COMPAT_INSTALL_PATH="$PWD" export STEAM_COMPAT_CLIENT_INSTALL_PATH="$HOME/.local/share/Steam" export STEAM_COMPAT_APP_ID=620980 export SteamEnv=1 export OXR_PARALLEL_VIEWS=1 ( sleep 20 pkill -TERM -f "[B]eat Saber.exe" || pkill -TERM -f "[B]eat Saber" || true sleep 2 pkill -KILL -f "[B]eat Saber.exe" || pkill -KILL -f "[B]eat Saber" || true ) & smoke_watchdog_pid=$! trap 'kill "$smoke_watchdog_pid" 2>/dev/null || true' EXIT steam-run "$HOME/.local/share/Steam/steamapps/common/Proton - Experimental/proton" \ run "$PWD/Beat Saber.exe" --no-yeet fpfc 2>&1 | tee /tmp/bs-smoke.log wait "$smoke_watchdog_pid" 2>/dev/null || true trap - EXIT ``` Useful launch arguments: | Argument | Use | | --- | --- | | `--verbose` | Opens the BSIPA console window. | | `--debug` | Promotes debug logs to console output. | | `--trace` | Enables very noisy BSIPA/internal traces. | | `fpfc` | First-Person Flying Controller, useful for non-VR menu testing. | | `--auto_play` | Built-in autoplayer for gameplay checks. | ## Log Checks In another terminal, or immediately after the launch returns: ```sh tail -F Logs/_latest.log ``` For a batch install, check for: - BSIPA startup reaches plugin loading. - the expected plugin names and versions appear in `Logs/_latest.log`. - there are no missing assembly or dependency-resolution failures. - there are no repeated unhandled exceptions from newly installed plugins. - the game reaches the main menu. After the first successful launch, `plugin-helper bootstrap-check --instance ` should pass. Ordinary plugin plans for lockfiles that include BSIPA depend on that recorded bootstrap state and the latest IPA log. For Setlist specifically: ```sh grep Setlist Logs/_latest.log ``` Expected Setlist signals include `platformUserId=...`, playlist lines with `hasSyncUrl=...`, and `beatLeaderOwnerConfirmed=...`. When testing real playlist sync, adding a map to an owned BeatLeader-synced playlist should log an HTTP success line. ## Teardown When the expected log lines are present before the watchdog fires, stop Beat Saber immediately from a second terminal instead of waiting for the smoke window to expire. ```sh pkill -TERM -f "[B]eat Saber.exe" || pkill -TERM -f "[B]eat Saber" || true sleep 2 pkill -KILL -f "[B]eat Saber.exe" || pkill -KILL -f "[B]eat Saber" || true ``` The bracketed pattern avoids matching the shell command that is running the cleanup. If Beat Saber still remains open, close the game window manually and then check for leftovers: ```sh ps -eo pid,ppid,stat,comm,args | rg -i '[B]eat Saber|[P]roton.*Beat Saber|[w]ineserver|[s]team-run' ``` If the smoketest fails, kill leftover Beat Saber, Wine, or Proton processes before retrying, then inspect `/tmp/bs-smoke.log`, Unity `Player.log` in the Proton compatdata, and the timestamped files under `Logs/`. ## Plugin Development Notes From Setlist These are relevant when `plugin-helper` installs locally built personal plugins. - PC BSIPA plugins are .NET Framework class libraries loaded by BSIPA. Linux `dotnet build` output is CIL and can be loaded by the Proton game instance. - BSMT-style builds may copy the DLL directly into `/Plugins/`; use `-p:DisableCopyToPlugins=True` when a build should not mutate the game tree. - `BeatSaberDir` in project user files or hint paths should point at the exact BSManager instance being targeted. - If a plugin build produces a shipped artifact, bump the plugin version before the successful build so the IPA log line identifies the artifact under test. - Setlist depends on BeatLeader being installed and signed in, PlaylistManager, and BeatSaberPlaylistsLib. Its normal install target is `Plugins/Setlist.dll`.