Skip to content

Commit 43d409d

Browse files
committed
WIP: Flatpak binary can now launch games on Steam Deck
- Game instructions are now passed as lists - All game runners need to support this (currently only SteamGameRunner_Linux.ts does) - Additional launch arguments setting needs to be reworked to implement a key/value approach
1 parent 696869e commit 43d409d

File tree

2 files changed

+116
-0
lines changed

2 files changed

+116
-0
lines changed

FLATPAK.md

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# Flatpak build
2+
3+
This is designed to run on the Steam Deck natively.
4+
5+
## Running under Wayland
6+
7+
Electron support for Wayland is iffy.
8+
9+
I'm using the [COSMIC](https://system76.com/cosmic) desktop environment and this particularly has issues with Electron + Wayland due to issues apparently handling zypak-helper.
10+
11+
This should however get you up and running:
12+
13+
```shell
14+
flatpak run com.github.ebkr.r2modman --ozone-platform=x11 --disable-gpu
15+
```
16+
17+
Fortunately, Steam Deck only uses Wayland in Desktop Mode, weirdly however this isn't an issue when running the AppImage version.
18+
19+
## Development
20+
21+
### Building
22+
23+
There's currently no nice way to hot-reload to test Flatpak behaviour. It has approximately a 2.5m build time (insane) and you need to reinstall the built binary.
24+
25+
You can use the following command to automate it for you though:
26+
27+
```
28+
yarn build-flatpak && flatpak install ./dist/electron/Packaged/r2modman-<version>-x86_64.flatpak
29+
```
30+
31+
## Thoughts and findings
32+
33+
> When referring to `flatpak-spawn`, this means launching with `flatpak-spawn --host`
34+
35+
This is hopefully useful to people developing for flatpak and outlines my struggles and thought process.
36+
37+
### Outcome
38+
39+
Getting Flatpak to invoke Steam has been rough. Steam, when launched from a Flatpak context, doesn't appear to forward additional arguments to the game process and instead just seems to run what's manually set in the arguments via the `Properties` section of a game.
40+
41+
So what's the fix?
42+
43+
The best solution I've come up with so far, and at the time of writing is yet to work fully, is to have a wrapper script that reads additional arguments via a separate file. Since we're doing things this way, it means we can also use the `steam://` protocol as we don't need to pass any additional arguments to the game process anymore, and we let the xdg handle opening the executable. It also means it likely works with Steam installed via Flatpak as we don't try to start multiple instances.
44+
45+
### Quirks
46+
47+
Unrelated though because it's not used anymore, but Node really doesn't like calling `flatpak-spawn`. Using `child_process` to call a separate script which then calls flatpak-spawn is fine and launches as expected, but calling it directly from the `child_process` library always fails to find it. Potentially weird sandboxing from Node?
48+
49+
Calling via flatpak-spawn seemed to launch Steam under a minimally sandboxed environment, and so additional permissions were needed to be passed so that audio could be accessed from within the client. Weirdly, if you already had Steam open however, the one running under the host would be used instead. It may be related to my Flatpak version or some odd Node quirk, or maybe even something I've done without realising.

public/web_start_wrapper.sh

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
#!/bin/sh
2+
3+
cd "$(dirname "$0")" || exit
4+
5+
# File to read arguments from
6+
ARGS_FILE="./wrapper_args.txt"
7+
8+
# Find the Steam executable from direct arguments (%command%)
9+
# Remaining arguments are appended to "$@"
10+
STEAM_EXECUTABLE=""
11+
for arg in "$@"; do
12+
if [ -z "$STEAM_EXECUTABLE" ] && [ "${arg#-}" = "$arg" ]; then
13+
STEAM_EXECUTABLE="$arg"
14+
else
15+
set -- "$@" "$arg"
16+
fi
17+
shift
18+
done
19+
20+
echo "Steam executable: $STEAM_EXECUTABLE"
21+
22+
# Read the $ARGS_FILE and further append arguments to $@
23+
# If a wrapper script is required (Linux native), then it should be the first argument
24+
# Pull it out and store it as that becomes the primary execution target when present
25+
WRAPPER_EXECUTABLE=""
26+
FIRST_LINE_CHECKED=false
27+
if [ -f "$ARGS_FILE" ]; then
28+
while IFS= read -r line || [ -n "$line" ]; do
29+
# Skip empty lines, allows comments for debugging
30+
[ -z "$line" ] && continue
31+
case "$line" in "#"*) continue ;; esac
32+
33+
if [ "$FIRST_LINE_CHECKED" = "false" ]; then
34+
FIRST_LINE_CHECKED=true
35+
36+
# If it's a file that exists AND isn't an option (no leading -)
37+
if [ "${line#-}" = "$line" ] && [ -f "$line" ]; then
38+
WRAPPER_EXECUTABLE="$line"
39+
echo "Found valid wrapper: $WRAPPER_EXECUTABLE"
40+
continue # Skip adding this line to $@ because it's the executable
41+
fi
42+
fi
43+
44+
# Everything else becomes an argument as part of $@
45+
set -- "$@" "$line"
46+
done < "$ARGS_FILE"
47+
fi
48+
49+
echo "Wrapper executable: $WRAPPER_EXECUTABLE"
50+
51+
# We forcibly clear args to prevent malicous injection
52+
# This also ensures that subsequent runs through Steam remain unmodded
53+
echo '' > "$ARGS_FILE"
54+
55+
if [ -z "$STEAM_EXECUTABLE" ]; then
56+
echo "Error: no executable provided by Steam %command%" >&2
57+
exit 1
58+
fi
59+
60+
if [ -n "$WRAPPER_EXECUTABLE" ]; then
61+
echo "Executing with wrapper executable: $WRAPPER_EXECUTABLE $STEAM_EXECUTABLE $@"
62+
exec "$WRAPPER_EXECUTABLE" "$STEAM_EXECUTABLE" "$@"
63+
else
64+
echo "Executing without wrapper executable: $STEAM_EXECUTABLE $@"
65+
exec "$STEAM_EXECUTABLE" "$@"
66+
fi
67+

0 commit comments

Comments
 (0)