Files
plugin-helper/docs/SMOKETEST.md
T
2026-06-29 10:56:57 -07:00

5.4 KiB

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:
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 <version> 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.

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:

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 <version> should pass. Ordinary plugin plans for lockfiles that include BSIPA depend on that recorded bootstrap state and the latest IPA log.

For Setlist specifically:

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.

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:

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 <BeatSaberDir>/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.