[PR #352] Add Battle.net app image #324

Open
opened 2026-10-15 12:50:51 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/games-on-whales/gow/pull/352
Author: @djmulder
Created: 7/31/2026
Status: 🔄 Open

Base: master ← Head: add-battlenet


📝 Commits (10+)

  • d152fc6 Add Battle.net app image
  • 1e81dbe battlenet: don't preserve 1000:1000 ownership when copying prefix to persistent storage
  • f1294e5 battlenet: make baked prefix world-readable so any PUID/PGID can copy it
  • 0d3296a battlenet: write Lutris-style Battle.net.config, disable locationapi, STAGING_SHARED_MEMORY
  • 5c3e71b battlenet: install Arial into the prefix like Lutris
  • 09f3e01 battlenet: split winetricks install from the Xvfb step
  • 36b6d5e battlenet: test-only Wolf app snippet (not for the PR)
  • f1f1a66 battlenet: install 32-bit GL/EGL/Vulkan libs (Battle.net is 32-bit, base image only has 64-bit)
  • 4b76833 battlenet: optional bnet.env in the persist dir to override launch flags/env while testing
  • 3f4a9e6 battlenet: optional BNET_RUNNER (e.g. umu-run) via bnet.env for testing Proton-GE

📊 Changes

7 files changed (+577 additions, -0 deletions)

View changed files

➕ apps/battlenet/_index.md (+60 -0)
➕ apps/battlenet/assets/screenshot.png (+0 -0)
➕ apps/battlenet/build/Dockerfile (+189 -0)
➕ apps/battlenet/build/ignore_capabilities.patch (+18 -0)
➕ apps/battlenet/build/scripts/20-fix-home-perms.sh (+7 -0)
➕ apps/battlenet/build/scripts/30-wow-userdata.sh (+94 -0)
➕ apps/battlenet/build/scripts/startup.sh (+209 -0)

📄 Description

Add Battle.net (Blizzard) app image

Summary

Adds a Battle.net launcher app for Games on Whales, so users can launch and play Blizzard/Activision games (World of Warcraft, Diablo, Overwatch, Call of Duty, ...) via Wolf + Moonlight streaming.

How it works

Battle.net runs through umu-launcher with GE-Proton in the Steam Linux Runtime (the same stack the Lutris image uses), so games get Proton's DXVK and vkd3d-proton (DX11 and DX12).

Everything is baked into the image at build time, so nothing is downloaded at start: GE-Proton (pinned, GE_PROTON_VERSION build arg), the Steam Linux Runtime, a Proton-created prefix and a complete Battle.net installation (installed headlessly via Xvfb). On first launch the prefix is copied to persistent storage, so logins and installed games survive restarts. Sway is the compositor (RUN_SWAY=true).

Key technical decisions

  • umu-run + Proton-GE instead of plain Wine, matching the Lutris image; Proton brings the fixes Battle.net needs.
  • GPU-rendered launcher UI (HardwareAcceleration=true in the baked Battle.net.config); software rendering is not used.
  • pressure-vessel copy in /dev/shm: each start gets its own directory, leftovers are cleaned up. This makes start-up take seconds instead of minutes (needs IpcMode: host and about 1.5 GB free).
  • Open-files limit: containers often start with a soft limit of 1024, which makes pressure-vessel fail ("Too many open files") and leaves a gray Sway. The start script raises the soft limit to the hard limit.
  • Zero config: without a mounted persist dir the prefix lives in ~/.bnet in Wolf's per-profile home, so a new profile needs no setup. A mount at /home/retro-persist is used when present.
  • Optional shared games folder: a mount at /games shows up as drive D: (also inside the pressure-vessel sandbox).
  • Per-user WoW data: WTF and Interface/AddOns of every installed flavor are bind-mounted per user over the shared install (/userdata if mounted, otherwise ~/userdata); new installs are picked up while the session runs. BNET_USERDATA_DISABLE=1 turns it off.
  • Auto-exit: the session ends 4 s after the client is closed and no game is left (BNET_AUTO_EXIT=0 disables it, BNET_EXIT_GRACE changes the wait).
  • Agent.dat cleanup: the Agent's PID file is removed on each start (it caused silent failures on restart).
  • Sway config: all windows float, explorer.exe (tray) is hidden in the scratchpad, title bars are on.
  • Diagnostics (off by default): BNET_DEBUG=1 in bnet.env writes session-trace.log, umu-last.log and session-summary.log. Extra environment can be set in bnet.env.

Wolf config.toml example

[[profiles.apps]]
title = "Battle.net"
start_virtual_compositor = true

    [profiles.apps.runner]
    type = "docker"
    name = "WolfBattlenet"
    image = "ghcr.io/games-on-whales/battlenet:edge"   # available after merge; until then build the image locally and use your own tag
    mounts = ["/path/to/games:/games:rw"]   # optional
    env = [
        "GOW_REQUIRED_DEVICES=/dev/input/* /dev/dri/* /dev/nvidia*",
        "XDG_RUNTIME_DIR=/tmp/runtime-retro",
        "RUN_SWAY=true"
    ]
    base_create_json = """
    {
      "HostConfig": {
        "IpcMode": "host",
        "CapAdd": ["SYS_ADMIN", "SYS_NICE", "SYS_PTRACE", "NET_RAW", "MKNOD", "NET_ADMIN"],
        "SecurityOpt": ["seccomp=unconfined", "apparmor=unconfined"],
        "DeviceCgroupRules": ["c 13:* rmw", "c 244:* rmw"]
      }
    }
    """

Tested with

  • Host: NixOS, AMD GPU (RX 9060 XT, Mesa 25.0.7 in the image), Wolf + Moonlight
  • Streaming: Wolf + Moonlight on a Surface Pro 10 (2880x1920, Windows client)
  • Games: Diablo III, StarCraft II, Warcraft III

Known limitations

  • When Battle.net opens a new login window inside a running session (mostly after "Log Out"), the keyboard may not reach the login page (mouse works), and now and then the window stays white or on the Battle.net logo (GPU process launch failed: error_code=63 in the Battle.net log, intermittent on RDNA4). Restart the session; with "Keep me logged in" ticked a fresh start logs in by itself. Cause not found yet, details in the README.
  • Battle.net setting "On game launch": "Keep Battle.net open" and "Exit completely" work; "Minimize" does nothing under Sway and the tray option hides the client.
  • Clipboard paste via Moonlight (Ctrl+Alt+Shift+V) does not work yet. Cause unknown: the same happens in the Lutris image, so it is not specific to Battle.net and could be anywhere in the Moonlight -> Wolf -> Sway -> XWayland -> Wine chain.
  • Battle.net may occasionally show the login screen after many rapid container restarts (Blizzard anti-fraud).

Screenshots

Battle.net running in GOW


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/games-on-whales/gow/pull/352 **Author:** [@djmulder](https://github.com/djmulder) **Created:** 7/31/2026 **Status:** 🔄 Open **Base:** `master` ← **Head:** `add-battlenet` --- ### 📝 Commits (10+) - [`d152fc6`](https://github.com/games-on-whales/gow/commit/d152fc61c0a66a3eff6ec53f5c3e71b423c9052b) Add Battle.net app image - [`1e81dbe`](https://github.com/games-on-whales/gow/commit/1e81dbeedee8a0fda06926bc719728232fd8ffed) battlenet: don't preserve 1000:1000 ownership when copying prefix to persistent storage - [`f1294e5`](https://github.com/games-on-whales/gow/commit/f1294e5ab8963e69f3ea61c8e396db99f8979d80) battlenet: make baked prefix world-readable so any PUID/PGID can copy it - [`0d3296a`](https://github.com/games-on-whales/gow/commit/0d3296ae5b16c648f9b7a87dd43cdb8488e3bca7) battlenet: write Lutris-style Battle.net.config, disable locationapi, STAGING_SHARED_MEMORY - [`5c3e71b`](https://github.com/games-on-whales/gow/commit/5c3e71b52842ed003ce7b354e70b5a9748319fb1) battlenet: install Arial into the prefix like Lutris - [`09f3e01`](https://github.com/games-on-whales/gow/commit/09f3e0161b6f4a650c4bc22ea193fa9d16c42920) battlenet: split winetricks install from the Xvfb step - [`36b6d5e`](https://github.com/games-on-whales/gow/commit/36b6d5e6bb6ecd0c7bac13f748dc0e2d7f8e5c20) battlenet: test-only Wolf app snippet (not for the PR) - [`f1f1a66`](https://github.com/games-on-whales/gow/commit/f1f1a66a5a298958a186ea33bdee3c5249984ab4) battlenet: install 32-bit GL/EGL/Vulkan libs (Battle.net is 32-bit, base image only has 64-bit) - [`4b76833`](https://github.com/games-on-whales/gow/commit/4b76833c74ac51d5c80df4c40df7ff91c41bb338) battlenet: optional bnet.env in the persist dir to override launch flags/env while testing - [`3f4a9e6`](https://github.com/games-on-whales/gow/commit/3f4a9e6f2d6326f344abf65392a0b8f25773c97c) battlenet: optional BNET_RUNNER (e.g. umu-run) via bnet.env for testing Proton-GE ### 📊 Changes **7 files changed** (+577 additions, -0 deletions) <details> <summary>View changed files</summary> ➕ `apps/battlenet/_index.md` (+60 -0) ➕ `apps/battlenet/assets/screenshot.png` (+0 -0) ➕ `apps/battlenet/build/Dockerfile` (+189 -0) ➕ `apps/battlenet/build/ignore_capabilities.patch` (+18 -0) ➕ `apps/battlenet/build/scripts/20-fix-home-perms.sh` (+7 -0) ➕ `apps/battlenet/build/scripts/30-wow-userdata.sh` (+94 -0) ➕ `apps/battlenet/build/scripts/startup.sh` (+209 -0) </details> ### 📄 Description # Add Battle.net (Blizzard) app image ## Summary Adds a Battle.net launcher app for Games on Whales, so users can launch and play Blizzard/Activision games (World of Warcraft, Diablo, Overwatch, Call of Duty, ...) via Wolf + Moonlight streaming. ## How it works Battle.net runs through [umu-launcher](https://github.com/Open-Wine-Components/umu-launcher) with GE-Proton in the Steam Linux Runtime (the same stack the Lutris image uses), so games get Proton's DXVK and vkd3d-proton (DX11 and DX12). Everything is baked into the image at build time, so nothing is downloaded at start: GE-Proton (pinned, `GE_PROTON_VERSION` build arg), the Steam Linux Runtime, a Proton-created prefix and a complete Battle.net installation (installed headlessly via Xvfb). On first launch the prefix is copied to persistent storage, so logins and installed games survive restarts. Sway is the compositor (`RUN_SWAY=true`). ## Key technical decisions - **umu-run + Proton-GE** instead of plain Wine, matching the Lutris image; Proton brings the fixes Battle.net needs. - **GPU-rendered launcher UI** (`HardwareAcceleration=true` in the baked `Battle.net.config`); software rendering is not used. - **pressure-vessel copy in `/dev/shm`**: each start gets its own directory, leftovers are cleaned up. This makes start-up take seconds instead of minutes (needs `IpcMode: host` and about 1.5 GB free). - **Open-files limit**: containers often start with a soft limit of 1024, which makes pressure-vessel fail ("Too many open files") and leaves a gray Sway. The start script raises the soft limit to the hard limit. - **Zero config**: without a mounted persist dir the prefix lives in `~/.bnet` in Wolf's per-profile home, so a new profile needs no setup. A mount at `/home/retro-persist` is used when present. - **Optional shared games folder**: a mount at `/games` shows up as drive `D:` (also inside the pressure-vessel sandbox). - **Per-user WoW data**: `WTF` and `Interface/AddOns` of every installed flavor are bind-mounted per user over the shared install (`/userdata` if mounted, otherwise `~/userdata`); new installs are picked up while the session runs. `BNET_USERDATA_DISABLE=1` turns it off. - **Auto-exit**: the session ends 4 s after the client is closed and no game is left (`BNET_AUTO_EXIT=0` disables it, `BNET_EXIT_GRACE` changes the wait). - **Agent.dat cleanup**: the Agent's PID file is removed on each start (it caused silent failures on restart). - **Sway config**: all windows float, `explorer.exe` (tray) is hidden in the scratchpad, title bars are on. - **Diagnostics** (off by default): `BNET_DEBUG=1` in `bnet.env` writes `session-trace.log`, `umu-last.log` and `session-summary.log`. Extra environment can be set in `bnet.env`. ## Wolf config.toml example ```toml [[profiles.apps]] title = "Battle.net" start_virtual_compositor = true [profiles.apps.runner] type = "docker" name = "WolfBattlenet" image = "ghcr.io/games-on-whales/battlenet:edge" # available after merge; until then build the image locally and use your own tag mounts = ["/path/to/games:/games:rw"] # optional env = [ "GOW_REQUIRED_DEVICES=/dev/input/* /dev/dri/* /dev/nvidia*", "XDG_RUNTIME_DIR=/tmp/runtime-retro", "RUN_SWAY=true" ] base_create_json = """ { "HostConfig": { "IpcMode": "host", "CapAdd": ["SYS_ADMIN", "SYS_NICE", "SYS_PTRACE", "NET_RAW", "MKNOD", "NET_ADMIN"], "SecurityOpt": ["seccomp=unconfined", "apparmor=unconfined"], "DeviceCgroupRules": ["c 13:* rmw", "c 244:* rmw"] } } """ ``` ## Tested with - **Host**: NixOS, AMD GPU (RX 9060 XT, Mesa 25.0.7 in the image), Wolf + Moonlight - **Streaming**: Wolf + Moonlight on a Surface Pro 10 (2880x1920, Windows client) - **Games**: Diablo III, StarCraft II, Warcraft III ## Known limitations - When Battle.net opens a new login window inside a running session (mostly after "Log Out"), the keyboard may not reach the login page (mouse works), and now and then the window stays white or on the Battle.net logo (`GPU process launch failed: error_code=63` in the Battle.net log, intermittent on RDNA4). Restart the session; with "Keep me logged in" ticked a fresh start logs in by itself. Cause not found yet, details in the README. - Battle.net setting "On game launch": "Keep Battle.net open" and "Exit completely" work; "Minimize" does nothing under Sway and the tray option hides the client. - Clipboard paste via Moonlight (`Ctrl+Alt+Shift+V`) does not work yet. Cause unknown: the same happens in the Lutris image, so it is not specific to Battle.net and could be anywhere in the Moonlight -> Wolf -> Sway -> XWayland -> Wine chain. - Battle.net may occasionally show the login screen after many rapid container restarts (Blizzard anti-fraud). ## Screenshots ![Battle.net running in GOW](apps/battlenet/assets/screenshot.png) --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
games-on-whales/gow#324
No description provided.