Skip to content

Architecture

Jason edited this page Sep 2, 2026 · 1 revision

Architecture

The setup flow (first launch)

SetupCoordinator runs automatically before the main UI ever appears. It tries, in order:

  1. Already have a ready engine cached? Use it, jump straight to bottle setup.
  2. A Sikarugir engine tarball is already downloaded but not extracted? Extract it locally (no network) - if more than one is available, ask which one (SetupStage.choosingEngine).
  3. Nothing local at all - download a real engine build directly from the public Sikarugir-App/Engines GitHub release (SikarugirEnginesRemote), into the exact same ~/Library/Application Support/Sikarugir/Engines/ folder Sikarugir Creator itself uses.
  4. Runtime libraries (~50 shared macOS runtime dylibs Wine needs) get fetched the same way if they're not already available locally, from the public Sikarugir-App/Wrapper template release (SikarugirWrapperTemplateRemote) - this is what lets a genuinely fresh install (the DMG alone, nothing else ever installed) finish setup with zero extra apps.
  5. Only if the direct download can't happen at all (offline, GitHub unreachable) does this fall back to opening a separately-installed Sikarugir Creator and waiting for it.

See Sources/ExeDock/Engine/SetupCoordinator.swift for the real state machine.

The bottle model

A Bottle (Sources/ExeDock/Models/Bottle.swift) is either:

  • .owned - a Wine prefix Playdock created and manages itself, under ~/Library/Application Support/ExeDock/Bottles/. This is what a fresh install uses.
  • .sikarugirWrapper(appPath:) - discovered read-only inside an existing Sikarugir wrapper app under ~/Applications/Sikarugir/*.app (built separately by Sikarugir Creator). Playdock never writes into one of these.

How a launch actually happens

ExeRunner.run(...) tries, in order, for a .sikarugirWrapper bottle:

  1. Configure-driven launch (SikarugirConfigureLauncher) - drives the wrapper's own bundled Configure.app via macOS Accessibility APIs: sets its "Windows app" field to the target exe, then clicks its own Test Run button. This is the most reliable path, found by live-inspecting a real wrapper's UI - not guessed.
  2. If that's unavailable, falls back to the wrapper's own CLI (Contents/MacOS/Sikarugir run <exe>).
  3. If that fails too, falls back to driving wine directly (wine start /unix <exe>).

.owned bottles currently only get steps 2-3 (see the open item in the issue tracker about extending Configure-driven launching to Playdock's own bottles too).

Local caches this app reads from

  • ~/Library/Application Support/Sikarugir/Engines/ - Wine engine builds (shared with Sikarugir Creator).
  • ~/Library/Application Support/Steam/appcache/librarycache/<appid>/ - Steam's own locally cached library art (portrait box art, icons), read directly when available instead of re-fetching from the network.
  • ~/Applications/Sikarugir/*.app - existing wrapper apps, read-only.

Playdock's own state lives entirely under ~/Library/Application Support/ExeDock/ (still named ExeDock on disk on purpose - see the README).

Clone this wiki locally