https://github.com/dark574/retromind
Linux-first, portable media manager for games, movies, books & more. Built with C# + Avalonia. Built by human creativity, powered by artificial intelligence
https://github.com/dark574/retromind
appimage avalonia csharp launcher linux mediacenter retrogaming wine
Last synced: 28 days ago
JSON representation
Linux-first, portable media manager for games, movies, books & more. Built with C# + Avalonia. Built by human creativity, powered by artificial intelligence
- Host: GitHub
- URL: https://github.com/dark574/retromind
- Owner: Dark574
- License: other
- Created: 2025-12-05T06:17:03.000Z (7 months ago)
- Default Branch: main
- Last Pushed: 2026-05-26T18:58:39.000Z (about 1 month ago)
- Last Synced: 2026-05-26T20:24:04.787Z (about 1 month ago)
- Topics: appimage, avalonia, csharp, launcher, linux, mediacenter, retrogaming, wine
- Language: C#
- Homepage: https://dark574.github.io/Retromind/
- Size: 18.1 MB
- Stars: 11
- Watchers: 1
- Forks: 2
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- License: COPYING
- Code of conduct: CODE_OF_CONDUCT.md
- Security: SECURITY.md
Awesome Lists containing this project
README
# Retromind
Built by human creativity, powered by artificial intelligence.
Dedicated to the digital spark that helped compile this reality.
Retromind is a Linux-first, portable media manager for organizing and launching your media library
(games, movies, books, comics, ...).
Built with **C#** + **Avalonia**.
## Website
Project homepage (GitHub Pages):
-
## Status
IMPORTANT:
Retromind is early alpha. Data formats (retromind_tree.json, app_settings.json) can change between releases without a migration path. Therefore, use this version more for testing than for a large, long-term library.
Work in progress. Expect breaking changes while features and data formats evolve.
See `docs/CHANGELOG.md` for version history.
## Key features (high-level)
- Library tree (areas/categories) on the left
- Cover/grid view in the center
- Details view on the right
- Drag & drop categories in the tree to reorder or move between parents (merge prompt on conflicts)
- Global search with classic title search plus optional metadata power-query mode
- Metadata scraping (depends on your API keys)
- Optional BigMode / controller-friendly UI with runtime themes
- Per-item manuals/documents
- Flexible launch configuration with wrappers, environment variables, and per-item arguments
- Portable library layout with relative paths (USB/external drive friendly)
- Optional AppImage portable HOME/XDG mode for Retromind runtime, with per-emulator overrides for child processes
## Screenshots
> Note: The screenshots are for demonstration purposes only.
> All product names, logos, and brands shown are property of their respective owners.
### Main library view

- Library tree on the left (areas / categories)
- Cover grid in the center
- Details panel on the right
### BigMode (controller-friendly UI)


- Large, readable layout for couch / TV usage
- Gamepad input support
- you can design and add your own theme through axaml files
## Requirements
- Linux (primary target)
- .NET SDK 10.0
- LibVLC runtime (required for this build; AppImage bundles it)
## Build AppImage (portable release, includes VLC)
This project ships a build script that creates a portable **AppImage** containing:
- a self-contained .NET build (no system .NET required)
- bundled **LibVLC + plugins** (video playback required)
- helper/runtime libraries exported from a Debian 12 (bookworm) build container
Note: When using the AppImage, you do not need a system-wide VLC installation because LibVLC is bundled.
The Wayland/X11 note below still applies because it affects how video is embedded into the Avalonia window.
### Requirements (host)
- Docker (for the full reproducible bookworm build pipeline)
- `curl` (to download `appimagetool` if missing)
### Build
```
chmod +x build/AppRun build/build-appimage.sh
./build/build-appimage.sh
```
The resulting AppImage will be created at:
- `dist/Retromind-x86_64.AppImage`
## Build & Run
### Rider
Open `Retromind.sln` and run the default configuration.
### CLI
```bash
dotnet restore
dotnet run --project Retromind.csproj
```
Start directly in BigMode:
```bash
dotnet run --project Retromind.csproj -- --bigmode
```
Or (if you run the built app directly):
```bash
./Retromind --bigmode
```
## Getting started (first run)
1. Build and run once (see “Build & Run”). Retromind will create `app_settings.json` under the portable data root (see below).
2. If you want to preconfigure settings, copy `app_settings.sample.json` to `app_settings.json` and adjust values.
3. For metadata scraping, configure API keys (see “API keys / Secrets”).
## Configuration (portable)
Retromind stores data under its portable data root for portability:
- AppImage: directory of the AppImage file (ENV: `APPIMAGE`)
- Otherwise: app base directory (build output folder)
Make sure the folder is writable.
Ignored runtime files (not committed):
- `Library/`
- `app_settings.json`
- `retromind_tree.json` (+ `.bak` / `.tmp`)
A sample settings file is provided:
- `app_settings.sample.json`
### LibVLC hardware decoding (BigMode previews)
Retromind uses **LibVLC** for video previews in BigMode.
The hardware decoding mode is configurable via `app_settings.json`:
```jsonc
"VlcHardwareDecodeMode": "none" // or "auto", "vaapi"
```
Supported values (depend on the host system / VLC build):
- `"none"`
Always use software decoding.
Safest default for unknown systems and portable AppImage builds.
- `"auto"`
Let VLC/FFmpeg pick a suitable hardware backend if available.
Good compromise on well-configured desktop systems.
- `"vaapi"`
Force VAAPI hardware decoding on compatible Linux systems (Intel/AMD iGPU).
Can noticeably reduce CPU usage and make high-resolution videos smoother,
but may fail on systems with broken/incomplete VAAPI setups.
If the value is missing or invalid, Retromind falls back to `"none"`.
For the **AppImage**, `"none"` is recommended as default for maximum compatibility.
On your own machine you can set `"vaapi"` in `app_settings.json` if VAAPI works
well (e.g. smoother BigMode videos, lower CPU load).
### AppImage portable HOME/XDG mode
Retromind can optionally redirect `HOME` and the `XDG_*` paths into a local
`Home/` folder next to the AppImage.
Important behavior:
- This setting affects the **Retromind AppImage process** itself.
- External launches (native apps, emulators, scripts, Steam/UMU/Proton wrappers) default to **host HOME/XDG** for compatibility.
- If you want portable child-process storage, set emulator/item overrides (`XDG_*`, optional `HOME`) explicitly.
- Portable mode is therefore **two-step**:
1) Retromind itself is portable via `UsePortableHomeInAppImage`
2) each launched tool/app is portable via emulator/item `XDG_*`/`HOME` overrides
Enable in `app_settings.json`:
```json
"UsePortableHomeInAppImage": true
```
Notes:
- Only applies when running as **AppImage**.
- Requires a **restart** to take effect.
- Existing `HOME`/`XDG_*` environment variables are not overridden if already set (unless forced mode is enabled).
- New emulator profiles default to **Host** XDG context for compatibility.
- In emulator settings, you can use presets to quickly set portable `XDG_*` (and optional `HOME`) per profile.
Switching back to normal mode:
- Set `"UsePortableHomeInAppImage": false` and restart Retromind.
- Retromind and external launches will use the host defaults again (unless you set explicit per-emulator/per-item overrides).
- Existing files under `Retromind/Home/` are kept as-is; they are not deleted automatically.
### Portable layout on USB sticks / external drives
Retromind is designed to work well from a single portable folder (e.g. on a USB stick)
together with your ROMs and native games. The core idea:
- The directory that contains the Retromind binary/AppImage is treated as the **portable data root**.
- Any files *inside* this directory (or subdirectories) are stored as **relative paths** in the library.
- On another Linux system, as long as you copy/mount the entire directory tree, Retromind will
resolve these relative paths correctly, regardless of the exact mountpoint or user name.
To enable relative launch paths, turn on **Prefer portable launch paths** in settings.
This will:
- store new imports under the data root as `LibraryRelative` paths
- migrate existing item launch paths during library saves
- normalize emulator settings paths (emulator executable, `XDG_*`, and known path-like env vars such as `HOME`/`DOTNET_CLI_HOME`/`PROTONPATH`) to data-root-relative values when possible
You can also trigger a one-time migration from the settings dialog.
A practical layout might look like this:
```text
Retromind/ Retromind-x86_64.AppImage Library/ ROMs/ SNES/ PSX/ NativeGames/ MyPortedGame/ Prefixes/ 123e4567-..._Some_Wine_Game/ Themes/
```
If you add ROMs or native games from anywhere *inside* the `Retromind/` folder:
- Retromind will detect that their absolute paths are under the portable root,
- convert them once to **library-relative** paths in the JSON database,
- and resolve them at runtime against the current AppImage directory.
This means:
- Moving the entire `Retromind/` folder to another machine or mounting it under a different path
will **not** break those entries.
- Only data stored outside of `Retromind/` (e.g. `/home/user/Downloads/…`) is saved as an absolute path
and depends on the original mountpoint.
### Wine prefixes and portability
When launching items that use Wine/Proton/UMU, Retromind can automatically create and
remember a **per-item Wine prefix** in the library:
- Prefixes are stored under `Library/Prefixes/…` (inside the portable root).
- The stored prefix path is **relative** to the library root.
- On another system, as long as the whole `Retromind/` folder moves together,
the same prefixes will be reused.
Note:
- The prefix itself is portable within Retromind’s folder.
- Game saves/configs remain host-user specific by default.
- If needed, you can override `XDG_*` (and optionally `HOME`) per emulator/item.
- Even with overrides, full portability is launcher-dependent; some tools still rely on host state.
### Wine/Proton runner version management
Retromind supports managed Wine/Proton runtime versions and lets you select them on:
- emulator level (default for all items using that emulator)
- item level (optional override)
#### 1) Configure available runner versions
In **Settings -> Runner** you can:
- add external Wine/Proton directories manually
- download/install GE-Proton releases (stored under `Emulators/ProtonVersions` in the portable root)
- remove versions (with replacement selection when still in use)
GE-Proton source:
- Repository: https://github.com/GloriousEggroll/proton-ge-custom
- Releases API used by Retromind: https://api.github.com/repos/GloriousEggroll/proton-ge-custom/releases
Retromind does not claim ownership of GE-Proton. Names, trademarks, and licenses remain with their respective owners.
Thanks to GloriousEggroll and all contributors for maintaining and publishing GE-Proton.
#### 2) Set emulator default runner
In **Settings -> Emulators -> Advanced**:
- enable **UseWinePrefix** for the emulator profile
- set **Runner type** (`Auto`, `UmuProton`, `Wine`, `Generic`)
- choose **Default runner version**
Notes:
- If `UseWinePrefix` is disabled, emulator-level default runner selection is disabled.
- `Auto` keeps compatibility heuristics; explicit types (`UmuProton`/`Wine`) are recommended for fixed setups.
#### 3) Optional item-level override
In **Edit Item -> Prefix (Wine/Proton/UMU)**:
- select a per-item **Wine/Proton version** to override the emulator default
- leave it on **None** to inherit the emulator default
- the dialog shows which runner is currently inherited from the emulator
Effective priority:
1. Item runner version (if set)
2. Emulator default runner version
3. No explicit runner version (launcher/env behavior only)
### Native games on the stick
Native games that live under the `Retromind/` directory tree (e.g. `Retromind/NativeGames/MyGame/...`)
are resolved the same way as ROMs:
- Internally, Retromind stores their launch paths relative to the portable root.
- On a different Linux system, launching still works as long as:
- the game files remain in the same relative position under `Retromind/`,
- system-level dependencies (e.g. libraries, drivers) required by the game are available.
Game-specific saves/configs stored under the user’s home directory are not moved automatically;
they will behave like any regular native Linux game when run on a different machine.
## Launch arguments placeholders
When configuring emulator profiles or per-item launch arguments, Retromind supports a few simple placeholders that are expanded at launch time:
- `{file}`
Full path to the primary launch file (quoted when needed).
- `{fileDir}`
Directory of the primary launch file (no trailing slash).
- `{fileName}`
File name including extension (e.g. `cabal.zip`).
- `{fileBase}`
File name without extension (e.g. `cabal`).
These placeholders can be used in both:
- **Emulator profile arguments** (`EmulatorConfig.Arguments`)
- **Per-item arguments** (`MediaItem.LauncherArgs`), which are combined with the profile arguments.
### Example: Flatpak MAME via emulator profile
To launch the Flatpak MAME build using ROM short names derived from the file path:
- **Executable path**:
`flatpak`
- **Default arguments**:
`run org.mamedev.MAME {fileBase}`
With a ROM stored as:
```text
/run/media/…/MAME/NameOfROM.zip
```
Retromind expands `{fileBase}` to `NameOfROM` and starts:
```bash
flatpak run org.mamedev.MAME NameOfROM
```
Make sure the ROM directory is part of MAME’s `rompath`, or pass it explicitly:
```text
run org.mamedev.MAME -rompath "{fileDir}" {fileBase}
```
which yields, for the example above:
```bash
flatpak run org.mamedev.MAME -rompath "/run/media/…/MAME" NameOfROM
```
### Example: Wine / UMU wrappers
For Wine-based games (e.g. via UMU) you can keep most logic in the emulator profile:
```text
umu-run --some-default-options {file}
```
and use per-item arguments only for game-specific flags, e.g.:
```text
--use-special-mode
```
Retromind combines profile + item arguments into a single command line while expanding the placeholders as described above.
## API keys / Secrets (Scrapers)
Retromind does **not** use any bundled default keys at runtime.
All scraper providers (TMDB, IGDB, TheGamesDB, Google Books, …) read their API credentials
from the scraper configuration (e.g. via the settings dialog). If no key is
configured, the corresponding scraper simply cannot be used.
Secrets are not stored in plain text. The app persists only encrypted fields
(e.g. `EncryptedApiKey`).
A template is provided for local development experiments:
- `Helpers/ApiSecretsTemplate.cs`
> NOTE: The main Retromind application does **not** use `ApiSecrets` for
> scraping. This template is only for custom tools or debugging scenarios.
### Scraper metadata coverage
The table below shows which metadata fields are currently populated by each provider.
`Source` is populated for all providers.
| Provider | Description | ReleaseDate | Rating | Developer | Genre | Platform | Publisher | Series | ReleaseType | SortTitle | PlayMode | MaxPlayers | CustomFields |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| IGDB | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | - | `IGDB.Slug` |
| TheGamesDB | yes | yes | yes | yes | yes | yes | yes | - | - | - | - | yes | - |
| TMDB | yes | yes | yes | - | - | - | - | - | yes | yes | - | - | - |
| OpenLibrary | - | yes | - | - | - | - | yes | yes | yes | yes | - | - | - |
| Google Books | yes | yes | - | - | - | - | yes | - | yes | yes | - | - | - |
| ComicVine | yes | - | - | - | - | - | yes | yes | yes | yes | - | - | `IssueNumber`, `StartYear` |
Notes:
- `CustomFields` are provider-specific key/value pairs and may vary by API response quality.
- Missing values are normal when the upstream provider does not return that field for a specific item.
- EmuMovies is currently not listed here because its API is being reworked.
### Where to get API keys
You need to create your own API keys on the respective provider pages:
- **TMDB (The Movie Database)**
Create a free account at:
https://www.themoviedb.org/
Then go to *Settings → API* in your profile and request an API key (v3 auth).
Enter this key in the TMDB scraper configuration in Retromind.
- **IGDB (via Twitch Developer)**
1. Create a Twitch Developer account:
https://dev.twitch.tv/
2. In the Developer Console, create an application to obtain:
- `Client ID`
- `Client Secret`
3. Enter both values in the IGDB scraper configuration in Retromind.
- **TheGamesDB**
1. Create an account at:
https://thegamesdb.net/
2. Generate an API key in your account settings / API page.
3. Enter the key in the TheGamesDB scraper configuration in Retromind.
- **Google Books (optional)**
The Google Books API can be used without a key in many cases, but you may
configure an API key to raise limits:
https://console.cloud.google.com/apis/library/books.googleapis.com
Create a project, enable the Books API, and create an API key. Enter it in
the Google Books scraper configuration in Retromind.
Each user is responsible for their own API keys and must comply with the
respective provider terms of service.
## Wayland / X11 note (VLC video embedding)
Wayland is currently **fully disabled** in Retromind on Linux.
At startup, Retromind forces `AVALONIA_PLATFORM=x11` to keep VLC embedding and embedded authentication stable.
If you pass `--avalonia-platform=wayland` or `--avalonia-platform=auto`, it is ignored for now and Retromind still runs on X11.
Why this is currently disabled:
- As of **April 20, 2026**, Avalonia's official platform matrix states Linux desktop targets **X11** and that Wayland is in **private preview**.
Source: https://docs.avaloniaui.net/docs/overview/supported-platforms
- Retromind's Linux runtime depends on stable native integration for both **LibVLC embedding** and **embedded OAuth/WebView**. In our AppImage testing, Wayland paths caused native instability (including process-level crashes), which cannot be handled safely in managed code.
- Until Avalonia ships generally available, production-grade Wayland support for this stack, Retromind keeps Linux on X11 by policy.
Use:
```bash
dotnet run --project Retromind.csproj -- --avalonia-platform=x11
```
## SortTitle
- Retromind sorts media entries by `SortTitle` attribute if it is set.
- If `SortTitle` is empty, Retromind falls back to `Title`.
- This is useful for series ordering (for example: `Series 001 - ...`, `Series 002 - ...`).
## Search (Power Query)
- Available in both search fields: global search and local node search.
- Plain text terms search title by default.
- Field terms: `key:value` or `key=value`.
- Metadata completeness terms: `has:` and `missing:`.
- Year comparisons: `year:>=YYYY`, `year:>YYYY`, `year:<=YYYY`, `year:` searches custom field keys and values.
- `cfk:` searches only custom field keys.
- `cfv:` searches only custom field values.
- `cf.:` searches a specific custom field key (example: `cf.rating:5`).
Examples:
- `zelda` -> title-only search
- `platform:snes AND developer:nintendo`
- `maxplayers:2 AND status:completed`
- `year=1998 favorite=true`
- `year:>=1995 AND year:<2000`
- `missing:genre OR missing:developer`
- `has:genre AND NOT genre:unknown`
- `(genre:platformer OR genre:metroidvania) AND NOT missing:rating`
- `cf.rating:5`
- `zelda AND platform:switch`
## GOG (Experimental)
The native GOG integration is currently **experimental**.
Please test it carefully and expect rough edges or breaking behavior between alpha releases.
### Requirements
- Linux desktop session with X11 runtime path (Retromind currently forces `AVALONIA_PLATFORM=x11`).
- Secret store support:
- preferred: Secret Service (`secret-tool`, GNOME Keyring/KWallet/libsecret backend)
- fallback: in-memory session storage (non-persistent)
- For embedded OAuth login dialogs: host `libwebkit2gtk` runtime available.
- If embedded OAuth is unavailable, Retromind falls back to system browser login with manual callback URL input.
### Usage
- Import full GOG library into a dedicated node:
1. Create a new node.
2. Open node settings and mark it as a GOG node (`StoreProviderId = gog`).
3. Run **Add GOG media** on that node.
4. Retromind syncs owned GOG titles additively into that node.
- Add individual GOG items into any node:
1. Run **Add GOG media** on any target node.
2. Use the picker dialog and select only the titles you want to add.
### Update workflow (Experimental baseline)
- Update checks are only performed for installed GOG-linked items.
- Checks are triggered automatically:
- when selecting an installed GOG item in the UI
- and by a background sweep (currently every 24 hours)
- If an update is detected, Retromind shows:
- an update badge in the media details
- an **Update** action button (same panel as install/reinstall actions)
- Running **Update** reuses the existing installer flow (download + install) and then refreshes the stored install fingerprint metadata.
- Important baseline note:
- reliable version/signature comparison requires an install fingerprint from Retromind.
- If a title was installed outside Retromind or before this metadata existed, run one reinstall via Retromind to establish the baseline.
## Architecture
See [`docs/architecture.md`](docs/architecture.md).
For native GOG provider status and design notes, see [`docs/gog-provider.md`](docs/gog-provider.md).
## Contributing
Contributions are welcome!
Before opening issues or pull requests, please have a look at:
- [`CONTRIBUTING.md`](CONTRIBUTING.md) – contribution guidelines
- [`CODE_OF_CONDUCT.md`](CODE_OF_CONDUCT.md) – expected behavior in the project community
## License
GPL-3.0-only (see `COPYING`).