# Linux BSIPA Build Reference ## Source Notes This workflow comes from `/home/pleb/ops/beatsaber/setlist/docs/pc-modding.md` and `/home/pleb/ops/beatsaber/setlist/docs/bootstrap.md`. Prefer those local files and local clones under `~/src` over web copies when deeper reference material is needed. ## Toolchain - PC BSIPA plugins are usually .NET Framework `net472` class libraries. - Linux `dotnet` SDK 6+ can build them because output DLLs are platform-agnostic CIL loaded by Beat Saber under Proton. - `BeatSaberModdingTools.Tasks` supplies the MSBuild targets normally driven by Visual Studio/Rider BSMT extensions. - On this host, `dotnet --list-sdks` should show a usable SDK. NuGet is available for package inspection. ## Game References Point `BeatSaberDir` at a modded BSManager instance containing: ```text Beat Saber.exe Beat Saber_Data/Managed/ IPA/ Libs/ Plugins/ winhttp.dll ``` Preferred local managed instance root: ```text /home/pleb/.local/share/BSManager/BSInstances/ ``` Windows mirror root: ```text /home/pleb/Windows/Users/pleb/BSManager/BSInstances/ ``` Use `BeatSaberVersion.txt` for the exact game version. The manifest `gameVersion` normally uses the `major.minor.patch` prefix, not the build suffix. ## Project Configuration Prefer machine-local configuration in `.csproj.user`: ```xml /home/pleb/.local/share/BSManager/BSInstances/1.40.8 ``` Some projects use `LocalRefsDir` and set: ```xml $(LocalRefsDir) ``` For those, pass `-p:LocalRefsDir=/path/to/instance` or add a local `.csproj.user` property if the project imports it. When changing a project file for Linux portability, prefer the smallest explicit fix: - Add `Microsoft.NETFramework.ReferenceAssemblies.net472` when MSBuild reports missing .NET Framework reference assemblies. - Set or pass `DisableCopyToPlugins=True` for artifact-only builds. - Keep hint paths rooted at `$(BeatSaberDir)` where possible. - Do not add broad multi-version compatibility logic unless requested. ## Build Commands From the plugin checkout: ```bash dotnet restore dotnet build -c Release -p:DisableCopyToPlugins=True ``` For a Debug smoke build: ```bash dotnet build -c Debug -p:DisableCopyToPlugins=True ``` Expected outputs: ```text bin/Debug/.dll bin/Release/.dll bin/Release/zip/-.zip bin//Artifact/Plugins/.dll ``` The exact layout depends on BSMT version and project customization. ## BSMT Copy Behavior `BeatSaberModdingTools.Tasks` may copy built DLLs into the game directory. On Unix hosts, its process check can behave differently and some projects add a custom target to copy into `/Plugins/`. For builds that should not alter a live instance, pass both property names; different BSMT projects/targets surface different copy switches: ```bash -p:DisableCopyToPlugins=True -p:DisableCopyToGame=True ``` If the purpose is to install the built artifact, copy it into plugin-helper's state downloads and use `plugin-helper plan/apply`, or follow `docs/SMOKETEST.md` for intentional live validation. ## Common Reference Failures - `MSB3644` or missing `.NETFramework,Version=v4.7.2` reference assemblies: add `Microsoft.NETFramework.ReferenceAssemblies.net472`. - Missing game assemblies such as `Main.dll`, `HMUI.dll`, `UnityEngine.CoreModule.dll`: `BeatSaberDir` is wrong or incomplete. - Missing mod dependencies such as `BSML.dll`, `SongCore.dll`, `SiraUtil.dll`, `BeatSaberPlaylistsLib.dll`: install or point at an instance containing those plugins, or fetch the dependency DLL from its verified release only when appropriate. - `IPA.Loader.dll` missing: BSIPA is not bootstrapped in that instance. ## Artifact Handoff To plugin-helper For a built plugin DLL intended for a managed instance: ```bash mkdir -p .state/instances//downloads/ cp //bin/Release/.dll .state/instances//downloads//.dll sha256sum .state/instances//downloads//.dll ``` Then update registry/lock data only if the user asked to manage/install the artifact, and use: ```bash PYTHONPATH=src python -m plugin_helper --state-dir .state check --instance PYTHONPATH=src python -m plugin_helper --state-dir .state plan --instance --plugin PYTHONPATH=src python -m plugin_helper --state-dir .state apply ``` Inspect the generated plan before applying.