Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
* text=auto eol=lf
*.sh text eol=lf
Dockerfile text eol=lf
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
.DS_Store
local_state/
.idea/
local_state/
/unraid-plugin/
28 changes: 27 additions & 1 deletion apps/es-de/build-fedora/scripts/startup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,28 @@ set -e

source /opt/gow/bash-lib/utils.sh

# Link bind-mount paths into $HOME without nesting inside existing directories.
_link_host_mount() {
local target=$1 link=$2
if [[ -L "$link" ]] || [[ ! -e "$link" ]]; then
ln -sfn "$target" "$link"
elif [[ -d "$link" ]] && [[ -z "$(ls -A "$link" 2>/dev/null)" ]]; then
rmdir "$link" && ln -sfn "$target" "$link"
else
gow_log "WARN: ${link} is a non-empty directory; remove or merge into ${target} so host mounts work"
fi
}

gow_log "Starting Application preparation"

gow_log "Library symlinks for emulator configs"
_link_host_mount /ROMs "${HOME}/ROMs"
_link_host_mount /bioses "${HOME}/bioses"

if [[ -d /ROMs ]] && [[ -z "$(ls -A /ROMs 2>/dev/null)" ]]; then
gow_log "WARN: /ROMs is empty — set ROMs library in the plugin and run Fix mounts, then relaunch ES-DE"
fi

RA_CFG_DIR=$HOME/.config/retroarch
RPCS3_CFG_DIR=$HOME/.config/rpcs3
XEMU_CFG_DIR=$HOME/.local/share/xemu
Expand Down Expand Up @@ -47,7 +67,13 @@ if test -f $HOME/bioses/xbox_hdd.qcow2; then
fi

if test -f $ES_CFG_DIR/settings/es_settings.xml; then
gow_log "EmulationStation settings already exist, skipping"
gow_log "EmulationStation settings already exist, checking ROMDirectory"
if grep -q 'name="ROMDirectory"' "$ES_CFG_DIR/settings/es_settings.xml" \
&& ! grep -q 'name="ROMDirectory" value="/ROMs"' "$ES_CFG_DIR/settings/es_settings.xml"; then
gow_log "Normalizing ROMDirectory to /ROMs in es_settings.xml"
sed -i 's/name="ROMDirectory" value="[^"]*"/name="ROMDirectory" value="\/ROMs"/' \
"$ES_CFG_DIR/settings/es_settings.xml"
fi
else
mkdir -p $ES_CFG_DIR/settings/
cp -u /cfg/es/es_settings.xml $ES_CFG_DIR/settings/es_settings.xml
Expand Down
29 changes: 28 additions & 1 deletion apps/es-de/build/scripts/startup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,29 @@ set -e

source /opt/gow/bash-lib/utils.sh

# Link bind-mount paths into $HOME without nesting inside existing directories.
_link_host_mount() {
local target=$1 link=$2
if [[ -L "$link" ]] || [[ ! -e "$link" ]]; then
ln -sfn "$target" "$link"
elif [[ -d "$link" ]] && [[ -z "$(ls -A "$link" 2>/dev/null)" ]]; then
rmdir "$link" && ln -sfn "$target" "$link"
else
gow_log "WARN: ${link} is a non-empty directory; remove or merge into ${target} so host mounts work"
fi
}

gow_log "Starting Application preparation"

# Host bind mounts from Wolf config.toml land at /ROMs, /bioses, /media.
gow_log "Library symlinks for emulator configs"
_link_host_mount /ROMs "${HOME}/ROMs"
_link_host_mount /bioses "${HOME}/bioses"

if [[ -d /ROMs ]] && [[ -z "$(ls -A /ROMs 2>/dev/null)" ]]; then
gow_log "WARN: /ROMs is empty — set ROMs library in the plugin and run Fix mounts, then relaunch ES-DE"
fi

RA_CFG_DIR=$HOME/.config/retroarch
RPCS3_CFG_DIR=$HOME/.config/rpcs3
XEMU_CFG_DIR=$HOME/.local/share/xemu
Expand Down Expand Up @@ -47,7 +68,13 @@ if test -f $HOME/bioses/xbox_hdd.qcow2; then
fi

if test -f $ES_CFG_DIR/settings/es_settings.xml; then
gow_log "EmulationStation settings already exist, skipping"
gow_log "EmulationStation settings already exist, checking ROMDirectory"
if grep -q 'name="ROMDirectory"' "$ES_CFG_DIR/settings/es_settings.xml" \
&& ! grep -q 'name="ROMDirectory" value="/ROMs"' "$ES_CFG_DIR/settings/es_settings.xml"; then
gow_log "Normalizing ROMDirectory to /ROMs in es_settings.xml"
sed -i 's/name="ROMDirectory" value="[^"]*"/name="ROMDirectory" value="\/ROMs"/' \
"$ES_CFG_DIR/settings/es_settings.xml"
fi
else
mkdir -p $ES_CFG_DIR/settings/
cp -u /cfg/es/es_settings.xml $ES_CFG_DIR/settings/es_settings.xml
Expand Down
15 changes: 15 additions & 0 deletions apps/lutris/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,21 @@ An open-source gaming platform for Linux that allows you to install and manage g
including Steam, GOG, and more.
It simplifies the process of running games on Linux.

## Lutris library bind mount

Lutris stores runners, metadata, and game installs under `/var/lutris` (with symlinks from
`~/.config/lutris` and `~/.local/share/lutris`). Bind your host Lutris data directory:

```toml
mounts = [
"/mnt/user/appdata/gow/lutris:/var/lutris:rw",
]
```

The Unraid plugin applies this when **Lutris library** is set in Setup and you run
**Fix mounts**. The Wolf preset ships with `mounts = []` so the plugin can bind your
host path instead of an anonymous Docker volume.

# Gamepad-UI
![lutris-gamepad-ui](assets/gamepadui.png)

Expand Down
2 changes: 1 addition & 1 deletion apps/lutris/assets/wolf.config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ start_virtual_compositor = true
type = "docker"
name = "WolfLutris"
image = "ghcr.io/games-on-whales/lutris:edge"
mounts = ["lutris:/var/lutris/:rw"]
mounts = []
env = [
'WOLF_LUTRIS_GAMEPAD_UI_ENABLE=1',
"GOW_REQUIRED_DEVICES=/dev/input/event* /dev/dri/* /dev/nvidia* /var/lutris/",
Expand Down
4 changes: 4 additions & 0 deletions apps/lutris/build-fedora/scripts/startup-10-create-dirs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@

gow_log "[start-create-dirs] Begin"

if [[ ! -w /var/lutris ]] 2>/dev/null; then
gow_log "WARN: /var/lutris is not writable — bind-mount your Lutris library path in Wolf config (plugin Fix mounts)"
fi

if [ ${WOLF_LUTRIS_SKIP_CREATE_DIRS:-0} -eq 0 ]; then

# "library" will contain information about available games and installed games.
Expand Down
4 changes: 4 additions & 0 deletions apps/lutris/build/scripts/startup-10-create-dirs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@

gow_log "[start-create-dirs] Begin"

if [[ ! -w /var/lutris ]] 2>/dev/null; then
gow_log "WARN: /var/lutris is not writable — bind-mount your Lutris library path in Wolf config (plugin Fix mounts)"
fi

if [ ${WOLF_LUTRIS_SKIP_CREATE_DIRS:-0} -eq 0 ]; then

# "library" will contain information about available games and installed games.
Expand Down
22 changes: 20 additions & 2 deletions apps/pegasus/build-fedora/scripts/startup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,28 @@
set -e

source /opt/gow/bash-lib/utils.sh

# Link bind-mount paths into $HOME without nesting inside existing directories.
_link_host_mount() {
local target=$1 link=$2
if [[ -L "$link" ]] || [[ ! -e "$link" ]]; then
ln -sfn "$target" "$link"
elif [[ -d "$link" ]] && [[ -z "$(ls -A "$link" 2>/dev/null)" ]]; then
rmdir "$link" && ln -sfn "$target" "$link"
else
gow_log "WARN: ${link} is a non-empty directory; remove or merge into ${target} so host mounts work"
fi
}

source /opt/gow/launch-comp.sh

gow_log "Symlinking Bioses from /Bioses"
ln -sf /bioses $HOME
gow_log "Symlinking Bioses and ROMs from host mounts"
_link_host_mount /bioses "${HOME}/bioses"
_link_host_mount /ROMs "${HOME}/ROMs"

if [[ -d /ROMs ]] && [[ -z "$(ls -A /ROMs 2>/dev/null)" ]]; then
gow_log "WARN: /ROMs is empty — configure ROMs library in the plugin and run Fix mounts"
fi

#########################################
# Configure Pegasus
Expand Down
22 changes: 20 additions & 2 deletions apps/pegasus/build/scripts/startup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,28 @@
set -e

source /opt/gow/bash-lib/utils.sh

# Link bind-mount paths into $HOME without nesting inside existing directories.
_link_host_mount() {
local target=$1 link=$2
if [[ -L "$link" ]] || [[ ! -e "$link" ]]; then
ln -sfn "$target" "$link"
elif [[ -d "$link" ]] && [[ -z "$(ls -A "$link" 2>/dev/null)" ]]; then
rmdir "$link" && ln -sfn "$target" "$link"
else
gow_log "WARN: ${link} is a non-empty directory; remove or merge into ${target} so host mounts work"
fi
}

source /opt/gow/launch-comp.sh

gow_log "Symlinking Bioses from /Bioses"
ln -sf /bioses $HOME
gow_log "Symlinking Bioses and ROMs from host mounts"
_link_host_mount /bioses "${HOME}/bioses"
_link_host_mount /ROMs "${HOME}/ROMs"

if [[ -d /ROMs ]] && [[ -z "$(ls -A /ROMs 2>/dev/null)" ]]; then
gow_log "WARN: /ROMs is empty — configure ROMs library in the plugin and run Fix mounts"
fi

#########################################
# Configure Pegasus
Expand Down
17 changes: 17 additions & 0 deletions apps/retroarch/build-fedora/scripts/startup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,25 @@ set -e

source /opt/gow/bash-lib/utils.sh

# Link bind-mount paths into $HOME without nesting inside existing directories.
_link_host_mount() {
local target=$1 link=$2
if [[ -L "$link" ]] || [[ ! -e "$link" ]]; then
ln -sfn "$target" "$link"
elif [[ -d "$link" ]] && [[ -z "$(ls -A "$link" 2>/dev/null)" ]]; then
rmdir "$link" && ln -sfn "$target" "$link"
else
gow_log "WARN: ${link} is a non-empty directory; remove or merge into ${target} so host mounts work"
fi
}

gow_log "Starting RetroArch"

if [[ -d /ROMs ]] && [[ -z "$(ls -A /ROMs 2>/dev/null)" ]]; then
gow_log "WARN: /ROMs is empty — configure ROMs library in the plugin and run Fix mounts"
fi
_link_host_mount /ROMs "${HOME}/ROMs"

CFG_DIR=$HOME/.config/retroarch

# Copying config in case it's the first time we mount from the host
Expand Down
17 changes: 17 additions & 0 deletions apps/retroarch/build/scripts/startup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,25 @@ set -e

source /opt/gow/bash-lib/utils.sh

# Link bind-mount paths into $HOME without nesting inside existing directories.
_link_host_mount() {
local target=$1 link=$2
if [[ -L "$link" ]] || [[ ! -e "$link" ]]; then
ln -sfn "$target" "$link"
elif [[ -d "$link" ]] && [[ -z "$(ls -A "$link" 2>/dev/null)" ]]; then
rmdir "$link" && ln -sfn "$target" "$link"
else
gow_log "WARN: ${link} is a non-empty directory; remove or merge into ${target} so host mounts work"
fi
}

gow_log "Starting RetroArch"

if [[ -d /ROMs ]] && [[ -z "$(ls -A /ROMs 2>/dev/null)" ]]; then
gow_log "WARN: /ROMs is empty — configure ROMs library in the plugin and run Fix mounts"
fi
_link_host_mount /ROMs "${HOME}/ROMs"

CFG_DIR=$HOME/.config/retroarch

# Copying config in case it's the first time we mount from the host
Expand Down
18 changes: 18 additions & 0 deletions apps/steam/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,24 @@ It offers a vast library of games, community features, and cloud saving.

## Customization

### Steam library bind mount

Steam installs games under `~/.local/share/Steam` (especially `steamapps/`). Wolf must
bind your host Steam library into the session container, for example:

```toml
mounts = [
"/mnt/user/steam:/home/retro/.local/share/Steam:rw",
]
```

The Unraid plugin writes this automatically when you set **Steam library** in Setup and
run **Advanced → Fix mounts**. Mounting only into the Wolf service at `/etc/wolf/steam`
does **not** expose your library to the Steam app.

Proton compatibility data uses `~/.local/share/WolfSteam/pfx` by default on the Fedora
image; game installs themselves should live on the bound Steam library path.

### Directly launch a Steam game

In order to directly launch a Steam game from Moonlight you can just copy the existing `[[apps]]` entry for Steam,
Expand Down
17 changes: 16 additions & 1 deletion apps/steam/build-fedora/scripts/startup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,23 @@ source /opt/gow/bash-lib/utils.sh

gow_log "Steam startup.sh"

STEAMDIR="${HOME}/.local/share/Steam"
mkdir -p "$STEAMDIR"
if [[ ! -w "$STEAMDIR" ]]; then
gow_log "WARN: Steam directory is not writable — set Steam library in the plugin and run Fix mounts"
fi
STEAMDIR_LEGACY="${HOME}/.steam/steam"
mkdir -p "$(dirname "$STEAMDIR_LEGACY")"
if [[ -L "$STEAMDIR_LEGACY" ]] || [[ ! -e "$STEAMDIR_LEGACY" ]]; then
ln -sfn "$STEAMDIR" "$STEAMDIR_LEGACY"
elif [[ -d "$STEAMDIR_LEGACY" ]] && [[ -z "$(ls -A "$STEAMDIR_LEGACY" 2>/dev/null)" ]]; then
rmdir "$STEAMDIR_LEGACY" && ln -sfn "$STEAMDIR" "$STEAMDIR_LEGACY"
else
gow_log "WARN: ${STEAMDIR_LEGACY} is a non-empty directory; refusing to replace with symlink (manual cleanup required)"
fi

# Recursively creating Steam necessary folders (https://github.com/ValveSoftware/steam-for-linux/issues/6492)
mkdir -p "$HOME/.local/share/Steam/ubuntu12_32/steam-runtime"
mkdir -p "$STEAMDIR/ubuntu12_32/steam-runtime"
export WINEPREFIX="$HOME/.local/share/WolfSteam/pfx"
export STEAM_COMPAT_DATA_PATH="$WINEPREFIX"

Expand Down
10 changes: 5 additions & 5 deletions apps/steam/build-fedora/scripts/system-services.sh
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,11 @@ if [ -d "$STEAMDIR_LEGACY" ] && [ ! -L "$STEAMDIR_LEGACY" ]; then
gow_log "*** library, move ~/.steam/steam/* into ~/.local/share/Steam/ ***"
gow_log "*** manually, then remove ~/.steam so the symlink can be ***"
gow_log "*** recreated on the next boot. ***"
# Bail before Steam launches: starting Steam against a real (non-symlink)
# ~/.steam/steam can confuse the client and a half-broken first run is
# the kind of thing that ends in lost data. Better to fail cont-init
# loudly so the human notices than to limp on.
exit 1
if [[ ! -w "$STEAMDIR" ]]; then
gow_log "WARN: Continuing anyway — ensure Steam library host mount is configured (plugin Fix mounts)"
else
gow_log "WARN: Continuing — Steam library bind mount is present; fix ~/.steam/steam when convenient"
fi
fi

# Install Decky Loader. The PluginLoader binary is baked into the image
Expand Down
16 changes: 16 additions & 0 deletions apps/steam/build/scripts/startup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,22 @@ source /opt/gow/bash-lib/utils.sh

gow_log "Steam startup.sh"

# Host bind mount from Wolf config.toml should land at ~/.local/share/Steam
STEAMDIR="${HOME}/.local/share/Steam"
mkdir -p "$STEAMDIR"
if [[ ! -w "$STEAMDIR" ]]; then
gow_log "WARN: Steam directory is not writable — set Steam library in the plugin and run Fix mounts"
fi
STEAMDIR_LEGACY="${HOME}/.steam/steam"
mkdir -p "$(dirname "$STEAMDIR_LEGACY")"
if [[ -L "$STEAMDIR_LEGACY" ]] || [[ ! -e "$STEAMDIR_LEGACY" ]]; then
ln -sfn "$STEAMDIR" "$STEAMDIR_LEGACY"
elif [[ -d "$STEAMDIR_LEGACY" ]] && [[ -z "$(ls -A "$STEAMDIR_LEGACY" 2>/dev/null)" ]]; then
rmdir "$STEAMDIR_LEGACY" && ln -sfn "$STEAMDIR" "$STEAMDIR_LEGACY"
else
gow_log "WARN: ${STEAMDIR_LEGACY} is a non-empty directory; refusing to replace with symlink (manual cleanup required)"
fi

# Recursively creating Steam necessary folders (https://github.com/ValveSoftware/steam-for-linux/issues/6492)
mkdir -p "$HOME/.steam/ubuntu12_32/steam-runtime"

Expand Down
6 changes: 5 additions & 1 deletion website/content/dev/manual-build.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,8 @@ docker build -t gow/base-app --build-arg BASE_IMAGE=gow/base images/base-app/bui

Now you can use `gow/base-app` as the base image for your custom image.

{{% /details %}}
{{% /details %}}

## Testing on Unraid (Games on Whales plugin)

On Unraid, library bind mounts are applied by the [Games on Whales Unraid plugin](https://github.com/games-on-whales/unraid-plugin) into Wolf's `config.toml` (not only into the Wolf service container). After building Fedora app images locally, use the plugin's `dev-install-test.sh` to wipe, patch `runner.image`, run **Fix mounts**, and verify session mounts. See the plugin's `DEVELOPING.md` section *Clean install with custom GOW images*.
Loading