A two-part Punktfunk plugin that syncs the Playnite library into the host
game library as the `playnite` provider:
- exporter/ — a minimal C# Playnite GenericPlugin ("Punktfunk Sync") that
writes punktfunk-library.json on every library change. Reading Playnite's
live-locked LiteDB from outside isn't robust, so this adapter runs inside
Playnite. Builds net462 via reference assemblies; packaged as a .pext.
- src/ — the TS plugin (on @punktfunk/host, rom-manager shape): watches the
export, embeds covers as data URLs, reconciles via
PUT /library/provider/playnite, with a console-hosted web UI + standalone
fallback + CLI. Launch = playnite://playnite/start/<id>, run by the host
in the interactive session so Playnite performs the real launch.
Verified locally: backend tsc + 23 tests + biome clean, SPA build, C#
exporter build + .pext pack.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2.5 KiB
Punktfunk Sync — Playnite exporter
The Playnite side of @punktfunk/plugin-playnite: a minimal
GenericPlugin that writes
your library to punktfunk-library.json whenever it changes. The Punktfunk plugin on the host reads
that file and reconciles it into the streaming library.
It exists because Playnite keeps its library database (LiteDB) open and locked while running, so the only robust way to read the library — with correct install state, art paths and metadata — is from inside Playnite. This plugin does exactly that and nothing else: no network, no settings, no UI.
What it writes
On startup, on every OnLibraryUpdated, and (debounced) on any per-game add/update/remove, it writes:
%APPDATA%\Playnite\ExtensionsData\<plugin-guid>\punktfunk-library.json
Shape (kept in lockstep with ../src/export-schema.ts):
{
"schema": 1,
"generatedAt": "2026-07-18T21:00:00Z",
"playnite": { "version": "10.x", "mode": "Desktop" },
"games": [
{
"id": "e3b0c442-98fc-1c14-9afb-4c8996fb9242", // Playnite Guid = reconcile external_id
"name": "Hollow Knight",
"installed": true,
"hidden": false,
"source": "Steam",
"platforms": ["PC (Windows)"],
"cover": "C:\\Users\\me\\AppData\\Roaming\\Playnite\\library\\files\\ab\\cover.jpg",
"background": null,
"icon": null
}
]
}
Art paths are absolute (resolved via IPlayniteAPI.Database.GetFullFilePath). Filtering
(installed-only, hidden, per-source) happens on the Punktfunk side, so the export is the full library.
You can also trigger a write by hand: Playnite main menu → Punktfunk Sync → Export library to Punktfunk now.
Install (for users)
Double-click punktfunk-sync.pext — Playnite installs it like any add-on — and restart Playnite.
Grab the .pext from the repo's CI artifacts.
Build
Targets .NET Framework 4.6.2 (Playnite's runtime). Thanks to
Microsoft.NETFramework.ReferenceAssemblies it builds with the plain .NET SDK on any OS — no Windows
or MSBuild needed:
dotnet build PunktfunkSync.csproj -c Release
# output: bin/Release/PunktfunkSync.dll + extension.yaml (PlayniteSDK.dll is provided by Playnite)
Package the .pext (a zip of the two files):
( cd bin/Release && zip -j ../../punktfunk-sync.pext extension.yaml PunktfunkSync.dll )