Setlist

A small Beat Saber (PC, BSIPA) plugin that syncs in-game playlist edits back to BeatLeader so your playlists stay current outside the game — on the website, on your phone, or shared with friends.

What it does

When you add a map to a playlist in-game (via the standard PlaylistManager "Add to playlist" flow), Setlist:

  1. Watches PlaylistManager.Utilities.Events.playlistSongAdded.
  2. Checks whether the playlist is a BeatLeader-synced playlist owned by you — i.e. its customData.syncURL is an api.beatleader.com/playlist/guid/… URL and its customData.owner matches your platform user id.
  3. Serializes the updated playlist and POSTs it back to BeatLeader (POST /user/playlist?id=…&shared=…).

The POST reuses the BeatLeader mod's authenticated session — no extra login, no API token in your config, nothing to copy/paste. If BeatLeader is signed in, Setlist is signed in.

The result: edit playlists in VR; see them updated on the website and any device that consumes them, without alt-tabbing or running a sync script.

Requirements

See Setlist/manifest.json for the authoritative list.

Install

Drop Setlist.dll into Beat Saber/Plugins/ alongside BeatLeader and PlaylistManager (BSManager works fine). Confirm in Logs/_latest.log:

[INFO  @ ...] [Setlist|...] platformUserId=...
[INFO  @ ...] [Setlist|...] Playlist "...": hasSyncUrl=True, owner=..., ownerMatchesPlatform=true (...)

When you add a map to one of those playlists in-game you should then see:

[INFO  @ ...] [Setlist|...] Setlist BeatLeader sync: OK HTTP 200 playlist="..." body=...

Build (Linux / NixOS, no Visual Studio / Rider)

This whole plugin is built from the dotnet CLI on Linux — including NixOS — no BSMT IDE extension required. The Linux + Cursor toolchain (.NET SDK 9, BSMT MSBuild tasks, the missing-net472-reference-assemblies workaround, and the "copy DLL into Plugins/ on a Unix host" target) is documented in:

  • docs/pc-modding.md — full guide, adapted from the BSMG wiki for Linux + Cursor + LLM-assisted dev.
  • docs/bootstrap.md — exactly how this project was scaffolded (template, NuGet pins, BeatSaberDir, etc.).

Quick start once Setlist.csproj.user points at your install:

cd Setlist
dotnet restore
dotnet build -c Debug

Output: Setlist/bin/Debug/Setlist.dll, also copied into $BeatSaberDir/Plugins/Setlist.dll by the Unix-host post-build target.

How it integrates with the two host plugins

Both integrations are deliberately thin and live in a single project so they can be read end-to-end:

  • PlaylistManager — Setlist subscribes to its public Events.playlistSongAdded hook (same one used by the in-game UI flow). Notes on that flow live in docs/playlistmanager-add-map.md.

  • BeatLeader — Setlist references the shipped BeatLeader.dll, waits on BeatLeader's own Authentication._signedIn flag, and POSTs through Unity's UnityWebRequest so the cookies BeatLeader's HttpClient already has on the shared CookieContainer are reused. Background and the alternative "go through WebRequestFactory directly" approach are in docs/beatleader-playlist-api.md and docs/beatleader-api-samples.md.

Status

Early / personal-use. Currently scoped to:

  • Adds (one new song → one POST). Removes, reorders, renames, and bulk edits are not yet wired.
  • BeatLeader as the sync target. The same model would extend to other backends that accept a full-playlist upload.

See AGENTS.md for repo conventions (version-bump-on-build, smoketest, etc.) if you're contributing or letting an agent work in this repo.

Description
Update Beatleader playlists in-game
Readme 129 KiB
Languages
C# 100%