# OpenGamepadUI-itch An itch.io library plugin for [OpenGamepadUI](https://github.com/ShadowBlip/OpenGamepadUI), built against itch's official [butlerd](https://itch.io/docs/butler/launcher-integration.html) JSON-RPC launcher daemon (the same integration path the official itch.io app uses under the hood) rather than screen-scraping the itch desktop app. Owned games, install state, install/update/uninstall, and launching are all driven through butlerd. This plugin spawns `butler daemon --json ...` itself, so the itch.io desktop app doesn't need to be installed at all — only a `butler` binary, which this plugin downloads automatically on first run from itch's own [broth](https://broth.itch.zone/) distribution channel. ## Setup 1. Build and install the plugin (see below). 2. Generate an API key at . 3. Open the plugin's settings screen in OpenGamepadUI and paste it in. API key login was chosen over the OAuth + PKCE flow butlerd also supports, because OAuth requires registering a redirect URI / custom URL scheme with itch.io for a specific app, which doesn't make sense for a self-built, unpublished plugin. If you're distributing this plugin publicly, switching to OAuth is worth doing — see `Profile.LoginWithOAuthCode` in the [butlerd launcher guide](https://itch.io/docs/butler/launcher-integration.html). ## Requirements See the [OpenGamepadUI requirements](https://github.com/ShadowBlip/OpenGamepadUI#requirements). This plugin additionally needs `unzip` on the host (used to unpack the downloaded `butler` binary). ## Building Same as any other OpenGamepadUI plugin: ```bash make help make build make install ``` ## Known limitations / good next steps This was put together from butlerd's public spec rather than against a running instance, so a few corners are simplifications rather than the "real" solution. If you pick this up: - **Launch target discovery.** butlerd's `Launch` call is the "correct" way to start a game (it handles prerequisites, manifest actions, sandboxing, etc.), but OpenGamepadUI's library items launch via a plain `command` + `args` OS exec, not an RPC call. This plugin currently side-steps that by scanning each installed game's folder for an executable file and pointing `command` directly at it (`library_itch.gd::_find_executable`). That works for straightforward native builds but skips prerequisite installation and manifest-declared launch actions. Parsing `.itch/receipt.json.gz` in the install folder would give the authoritative answer. - **Field names.** The JSON-RPC field names used in `itch_client.gd` follow butlerd's documented camelCase convention, cross-checked against the [butlerd Go package docs](https://pkg.go.dev/github.com/itchio/butler/butlerd) for the calls that matter most (`Install.Queue`/`Install.Perform`, `Uninstall.Perform`). A couple of the less-central ones (`Launch`, `Profile.LoginWithAPIKey`, `Fetch.ProfileOwnedKeys`) were written from the documented naming convention rather than a byte-for-byte spec check — worth diffing against your `butler`'s actual behavior (run with `--log` to see the raw JSON-RPC traffic) if a call comes back with an unexpected error shape. - **Install location picker.** `_ensure_install_location()` silently picks the first existing install location, or creates one under the plugin's own data directory. No UI for choosing/managing install locations yet. - **Settings screen.** Uses plain Godot `Control` nodes rather than OpenGamepadUI's themed widget set (the one the built-in Steam plugin's settings scene uses), since this was written without editor access to those theme resources. - **`has_update()`** always returns `false` — wiring up `CheckUpdate` (and periodic background polling) is a natural next step. - **No progress→UI wiring.** `install_progressed` is re-emitted from raw butlerd notifications but not yet mapped back to a `LibraryLaunchItem` through `LibraryManager` (see the TODO in `library_itch.gd`). ## How it fits together ``` plugin.gd entrypoint; wires client + library + settings menu core/itch_client.gd spawns butlerd, speaks JSON-RPC 2.0 over TCP to it core/library_itch.gd extends Library; turns butlerd data into LibraryLaunchItems core/itch_settings.* API key entry screen ```