Files
plugin-helper/docs/SMOKETEST.md
T

6.3 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.

Several ERROR and WARNING lines are benign on a healthy 1.44.1 stack (older manifest warnings, BeatLeader optional-interop probes, brief AudioTimeSyncController resume noise, custom-map Leaderboard id ... not found, transient KeyRemapper controller reconnects, and similar). See docs/notes/install-and-verify-plugins-1.44.1.md before treating every red log line as a plugin failure.

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 ownerMatchesPlatform=.... When testing real playlist sync, adding a map to an owned BeatLeader-synced playlist should log an HTTP success line.

Windows

From the instance directory, for example C:\Users\pleb\BSManager\BSInstances\1.44.1:

Start-Process -FilePath ".\Beat Saber.exe" -ArgumentList "--no-yeet","fpfc" -WorkingDirectory $PWD

Wait until Logs\_latest.log contains MainSystemInit, or about 20 seconds, then stop the process:

Stop-Process -Name "Beat Saber" -Force

Confirm no Beat Saber process remains. The Proton recipe above is for Linux.

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.