Files
plugin-helper/docs/ROADMAP.md
T

5.5 KiB

plugin-helper Roadmap

This roadmap tracks ideas that are useful but not part of the first safe CLI slice.

Current Direction

The initial tool should stay conservative:

  • Python owns instance discovery, dry-run plans, activation, install state, uninstall, and UserData backups.
  • Release assets are selected through registry and lockfile data.
  • Prefer upstream GitHub release artifacts for normal plugins. Use BeatMods as compatibility/dependency metadata, and as an artifact source only for inaccessible upstream artifacts, BeatMods-only packages, or framework/library dependencies.
  • Mutating operations apply an explicit plan and record exact file hashes.
  • Nix packages plugin-helper, but does not directly manage the mutable Beat Saber tree.

This works well while Beat Saber is still launched from a Windows install or a mounted Windows filesystem.

Future: Nix-Orchestrated Plugin Sets

Once Beat Saber is running on Linux through Steam Proton, it may make sense to let Nix orchestrate the plugin payload itself.

The core idea:

Nix flake / plugin set
  fetch exact GitHub release assets
  verify hashes
  unpack and normalize Plugins/, Libs/, IPA/Pending/
  produce /nix/store/...-beatsaber-plugins-<game-version>/

plugin-helper
  run nix build .#pluginSets.<game-version>
  compare the resulting tree to the target Beat Saber instance
  create a normal dry-run plan
  copy or link files into the instance
  record activation state

In that model, the plugin folder effectively gets a reproducible lock:

  • flake.lock pins Nix inputs.
  • A plugin-set definition pins plugin repositories, tags, release assets, and hashes.
  • The generated Nix output is a canonical, immutable plugin tree for one Beat Saber version.
  • plugin-helper remains the safety layer around activation and rollback.

Why Wait For Proton

For the current dual-boot Windows path, a pure Nix-store plugin tree is awkward:

  • Windows cannot use /nix/store paths directly.
  • Linux symlinks inside a mounted Windows filesystem may not behave the way native Windows Beat Saber expects.
  • Some plugins may create or expect colocated mutable files.

When running through Proton on Linux, Nix-store outputs and symlink activation become much more practical. Even then, copy mode should remain available for plugins that expect writable colocated files.

Activation Modes

A future Nix-backed planner should support at least these activation modes:

  • copy: materialize files into the Beat Saber instance. Best compatibility, including mounted Windows trees.
  • symlink: link plugin files from the Nix output. Best reproducibility and cleanup on Linux/Proton.
  • materialize: link immutable files where safe and copy known-mutable files.

All modes should still produce the same kind of explicit plan before applying.

Proposed Milestones

  1. Keep the Python safety harness stable: scan, plan, apply, uninstall, and backups.
  2. Model BSIPA bootstrap as a first-class install phase, preferring upstream GitHub release artifacts while preserving BeatMods zipHash/version metadata when used for verification or fallback.
  3. Resolve BeatMods dependency closures by mod-version id for verified mods before ordinary batch planning, but keep artifact sourcing GitHub-preferred.
  4. Model one real plugin end to end with the current TOML lockfile and local asset planning.
  5. Add a Nix function that fetches and unpacks one locked plugin asset into a normalized tree.
  6. Generate a full plugin-set derivation for one Beat Saber version.
  7. Teach plugin-helper plan to compare a Nix output tree against an instance.
  8. Add --activation-mode copy|symlink|materialize.
  9. Move compatibility and dependency metadata toward shared data that both Python and Nix can consume.

Warning Follow-Ups From 1.44.1 Bootstrap

The first 1.44.1 BSIPA/SongCore smoketest worked, but it produced warnings worth tracking separately from install success:

  • BSML, SiraUtil, and SongCore have older target game-version metadata even though BeatMods verifies the selected releases for 1.44.1. Decide whether plugin-helper should treat BeatMods verification as a compatibility override.
  • The first bootstrap used BeatMods CDN artifacts for speed. BSIPA, BSML, and SiraUtil have now been matched to byte-identical upstream GitHub release assets. SongCore remains a BeatMods CDN fallback because the BeatMods preferred repo Kylemc1413/SongCore currently exposes no matching 3.16.0 GitHub release asset.
  • BSML reports missing Windows fonts under Proton. This is likely cosmetic, but may affect Unicode text rendering in mod UI.
  • SongCore warns that Beat Saber_Data/CustomWIPLevels/Cache has no Info.dat. Either create the expected cache directory shape or classify this warning as harmless.
  • SongCore could not read the audio rate for the built-in Magic.wav custom level and approximated duration from map length. Check whether this is a bundled-song oddity or a broader audio metadata issue.
  • The smoketest launcher can leave Beat Saber running after timeout. Prefer explicit teardown and consider a helper command that starts, watches logs, and kills the process tree deterministically.

Open Questions

  • Should the human-edited source of truth be TOML, Nix, or TOML that generates Nix?
  • How should plugin-specific unpack rules be represented without making Nix expressions too noisy?
  • Which plugin files are known to need mutability after install?
  • Should the Nix output include BSIPA itself, or continue assuming BSIPA is provided by the game instance manager?
  • How should updates be proposed: Python querying GitHub, Nix update scripts, or both?