Motivation
I installed the Steam game platform and Proton compatibility layer on my Ubuntu computer before, which allows running Windows games on Linux. However, I didn’t play games much, so I didn’t study it carefully. I just knew that the Proton compatibility layer is quite powerful, and most games run without any problems, even if the “system requirements” of the game only show support for Windows systems.
Later, I installed an Nvidia RTX 4060 Ti graphics card, mainly to learn CUDA programming and deep learning. Recently, “Black Myth: Wukong” became very popular, and my roommate wanted to play on my computer, so he logged into his Steam account on my computer and downloaded “Black Myth: Wukong”. He found that it ran without any problems.
After watching my roommate play for a while, I also wanted to try it, but I didn’t want to switch Steam accounts back and forth. So I created another system account on Ubuntu, started and logged into Steam, but I found that the games downloaded by my roommate on another account did not appear on my account. Since these games are very large, I don’t want to download them again, so I tried to run the games downloaded by my roommate on my account. In the process, I encountered one problem after another, and finally solved it. Here I record it for reference for those who encounter the same problem.
Prerequisites
If you only want to play Steam games on Linux by yourself, you only need to install Steam and Proton. You can follow the steps in my previous article “Nvidia GPU Settings on Ubuntu: Games, CUDA, Deep Learning, Docker, etc.”. If you don’t want to click in and read, I’ll list the steps here briefly:
Install Steam
- Download the Steam installation package:
|
|
- Install Steam:
|
|
- Install missing dependencies:
|
|
- Run Steam:
|
|
- Log in to your Steam account
Install Proton
In Steam, select games that can run on Linux, then click Settings
, in the Steam Play
tab, check Enable Steam Play for supported titles
and Enable Steam Play for all other titles
, then select a Proton version from the Steam Play
drop-down menu, and click OK
.
After Proton is installed, you can run Windows games on Linux.
Install Games
If you are using Steam for the first time and have not purchased any games, you can choose some free games for testing, such as “Dota 2”, “Counter-Strike: Global Offensive”, etc.
Share Games Among Multiple Users
If you want multiple users to play the same game, and don’t want to download it again (after all, a large game may have tens of GBs or even hundreds of GBs), you can continue to see how I operate.
Steam Runtime Environment
Before creating a second user and sharing the same game files, we need to understand the runtime environment of Steam on Linux and the location of the main files.
After installing Steam and Proton according to the steps above, Steam is installed in the system directory, so all users can use the Steam client.
When a user user1
starts the Steam client, Steam will create a .steam
directory in the home directory of the user1
user, which contains the user’s Steam configuration files, game files, etc. In the .steam
directory, there is a steam
directory, which contains the user’s Steam client program, and a steamapps
directory, which contains the user’s downloaded game files.
Therefore, if we want to reuse a game, the essence is to let other users also access the game files in the /home/user1/.steam/steam/steamapps
directory.
Create a Second User
-
We create a new system account for the second user, add it to the
sudo
group, and set a password:1 2 3
sudo adduser user2 sudo usermod -aG sudo user2 sudo passwd user2
-
Switch to the
user2
user:Click the user icon in the upper right corner of the screen, select
Switch Account
, and then select theuser2
user to log in. -
Open and log in to Steam:
After opening the Steam client, Steam will create a
.steam
directory in the home directory of theuser2
user, but the.steam/steam/steamapps
directory of theuser2
user does not contain game files. Therefore, when you click theLibrary
page, you will find that the library does not show the games downloaded by theuser1
user.Next, we will mainly solve this problem, allowing the
user2
user to access the game files downloaded by theuser1
user and run the games normally.
Share Game Files
-
The game files downloaded by the
user1
user are located in the/home/user1/.steam/steam/steamapps
directory. However, we want multiple users to share these game files, so it is best to move these game files to a public directory, such as/opt/games/steam
.1 2
sudo mkdir -p /opt/games/steam sudo mv /home/user1/.steam/steam/steamapps /opt/games/steam
-
To allow the
user2
user to access the game files in the/opt/games/steam
directory, we need to set the permissions of the/opt/games/steam
directory to755
:1
sudo chmod 775 /opt/games/steam
Next we create a new user group
steam
and add theuser1
anduser2
users to this user group:1 2 3
sudo groupadd steam sudo usermod -aG steam user1 sudo usermod -aG steam user2
Then, we set the user group of the
/opt/games/steam
directory tosteam
:1
sudo chown -R user1:steam /opt/games/steam
Finally, we need to set the
setgid
permission for the shared folder, so that any files and directories created in the shared folder will have the same user group as the user group of the shared folder. That is, the user group of/opt/games/steam
issteam
, and the user group of files and directories created in/opt/games/steam
will also besteam
:1
sudo chmod g+s /opt/games/steam
-
To allow the Steam client of the
user1
user to access the game files in the/opt/games/steam
directory, we need to create a symbolic link in the home directory of theuser1
user:1
ln -s /opt/games/steam/steamapps /home/user1/.steam/steam/steamapps
Then we open the Steam client under
user1
, click theLibrary
page, and you will find that the previously downloaded game files are there. If you don’t see it, try restarting the Steam client or restarting the computer. -
Similarly for the
user2
user, we need to create a symbolic link in the home directory of theuser2
user:1
ln -s /opt/games/steam/steamapps /home/user2/.steam/steam/steamapps
Then we open the Steam client under
user2
(you may need to restart the Steam client or restart the computer first), click theLibrary
page, and you should see the previously downloaded game files.However, if you click the
Play
button, you will find that the game does not start, and there may be no prompts. If you want to find the problem through error logs, you can exit the Steam client, and then run the Steam client in the terminal, so you can see the output information of Steam in the terminal, something like this:1
pressure-vessel-wrap[44758]: E: openat(/opt/games/steam/steamapps/common/SteamLinuxRuntime_sniper/sniper_platform_0.20240806.97927/files/.ref): Permission denied
Or like this:
1 2 3 4 5
pressure-vessel-wrap[4109614]: W: For best results, "/opt/games/steam/steamapps/common/SteamLinuxRuntime_sniper/sniper_platform_0.20240820.99315/files" and "/opt/games/steam/steamapps/common/SteamLinuxRuntime_sniper/var/tmp-7P6EU2/usr" should both be on the same fully-featured Linux filesystem. Adding process 4109770 for gameID 1264970 wineserver: /opt/games/steam/steamapps/compatdata/1264970/pfx is not owned by you wine: using kernel write watches, use_kernel_writewatch 1. wine: '/opt/games/steam/steamapps/compatdata/1264970/pfx' is not owned by you
You can also right-click on the game in the
Library
page, then selectProperties
, clickVerify Integrity
in theLocal Files
tab, and you will find that the integrity check fails. -
The above problem is quite strange, because we have set the permissions of the
/opt/games/steam
directory to755
, and added theuser1
anduser2
users to thesteam
user group, but the error message above indicates that the Steam client under theuser2
user still cannot access the/opt/games/steam/steamapps/common/SteamLinuxRuntime_sniper/sniper_platform_0.20240806.97927/files/.ref
file. Even more strange is that the size of this file is 0! I don’t know what this file is for, but after some exploration, I found some related discussions online:- https://ubuntuforums.org/showthread.php?t=2494677
- https://github.com/ValveSoftware/Proton/issues/4820
- https://github.com/ValveSoftware/steam-for-linux/issues/3942
These discussions mainly propose two solutions:
-
After switching system accounts, change the ownership of the
/opt/games/steam
directory to the current user:1
sudo chown -R user2:steam /opt/games/steam
This way, the
user2
user can access all files in the/opt/games/steam
directory.However, this solution is a temporary solution, because every time you switch system accounts, you need to change the ownership of the
/opt/games/steam
directory, which is obviously inconvenient. -
The essence of the above problem is that the Wine used by the Proton compatibility layer does not allow users to access prefix directories owned by other users for security reasons. Therefore, the solution is to create different prefix directories for different users when starting Steam. The prefix directory of Wine is an important concept of the Proton compatibility layer, which stores the game’s configuration files, cache files, etc. By default, Proton stores the prefix directory in the
~/.steam/steam/steamapps/compatdata/
directory, but we can modify the Proton code to create different prefix directories according to the current user.To implement this solution, we need to modify the Proton code and then recompile Proton. In fact, there are only two lines of code to modify, see Proton pull request #4861. This pull request was created on GitHub in May 2021, but it has not been merged so far. I don’t know why the Proton developers have not merged this simple but useful pull request. Since the official has not added this feature, we will implement it ourselves next.
Modify and Compile Proton
-
First, we need to download the source code of Proton:
1 2
git clone --recurse-submodules https://github.com/ValveSoftware/Proton.git proton cd proton
-
Then, we need to switch to a stable branch, such as
proton_9.0
. We also need to update the submodules:1 2
git checkout proton_9.0 git submodule update --init --recursive
-
Next, we need to modify the code of Proton. To do this, we create a new branch, for example, called
myfeature-pr4861
:1
git checkout -b myfeature-pr4861
Open the
proton
file in the root directory of the Proton project (this is a Python file), find the initialization function__init__
of theCompatData
class. We need to modify the lineself.base_dir
and add a line. The modified code is as follows:1 2 3 4
class CompatData: def __init__(self, compatdata): self.base_dir = compatdata + "/" + str(os.getuid()) + "/" os.makedirs(self.base_dir, exist_ok=True)
We only need to modify these two lines of code, see Proton pull request #4861.
This idea is actually very simple. The underlying layer of Proton uses Wine to run games, and the prefix directory of Wine is stored in the
~/.steam/steam/steamapps/compatdata/
directory. Before making the above modifications, when we run a game asuser1
, Proton will store the prefix directory in the~/.steam/steam/steamapps/compatdata/
directory, and its ownership isuser1
. When we run the same game asuser2
, Wine will try to access the prefix directory in the~/.steam/steam/steamapps/compatdata/
directory, but because its ownership isuser1
, Wine will refuse to access it.The above modification is to let Proton create different prefix directories according to the current user. For example, if the
uid
ofuser1
is1000
and theuid
ofuser2
is1001
, whenuser1
runs a game, Proton will store the prefix directory in the~/.steam/steam/steamapps/compatdata/1000/
directory, and its ownership isuser1
; whenuser2
runs the game, Proton will store the prefix directory in the~/.steam/steam/steamapps/compatdata/1001/
directory, and its ownership isuser2
. This solves the ownership conflict problem mentioned above. -
Next, we compile Proton. Proton uses container technology, so we need a container tool, such as Docker or Podman. Docker is already installed on my computer, but Docker generally requires
sudo
permission to run, which will cause a series of permission issues. Therefore, I recommend using Podman, which does not requiresudo
permission.-
First, we need to install Podman:
1
sudo apt install podman
-
Then, we create a build folder, which can be placed at the same level as the Proton project:
1 2 3
cd .. mkdir build cd build
-
Next, we configure the build environment using the configuration tool provided by the Proton project:
1
../proton/configure.sh --enable-ccache --build-name=myfeature-9.0-pr4861
-
Finally, we start compiling Proton:
1
make
-
-
After the compilation is completed, we create the installation files of Proton:
1
make redist
This way, a
redist
directory will be generated in thebuild
directory, which contains the installation files of Proton. -
Install Proton. For user-defined compatibility layers, we can place them in the
~/.steam/root/compatibilitytools.d/
directory. We copy theredist
directory to the~/.steam/root/compatibilitytools.d/
directory:1
cp -r redist ~/.steam/root/compatibilitytools.d/myfeature-9.0-pr4861
Note that no matter which account uses Steam, we need to copy the
redist
directory to the~/.steam/root/compatibilitytools.d/
directory and change the ownership of the directory to the current user. For example, if it is theuser_x
user, we can do this:1
sudo chown -R user_x:user_x ~/.steam/root/compatibilitytools.d/myfeature-9.0-pr4861
Use Customized Proton
After completing the above steps, Steam will be able to detect our customized Proton version.
No matter which account uses Steam, we only need to select our customized Proton version in Steam. After opening Steam, click Steam
in the upper left corner, then select Settings
, select Compatibility
in the sidebar, select our customized Proton version myfeature-9.0-pr4861
from the drop-down menu under Run other products with
, and then click OK
.
Finally, select a game and click Play
, a dialog box will pop up asking you whether to run the game in compatibility mode. I found that it is actually okay not to select compatibility mode:
![Run in compatibility mode](https://img.jinli.io/images/2024/09/19/steam_compatible_mode.md.png)
Steam will spend some time compiling shaders, and then you can enter the game interface!
![Black Myth: Wukong](https://img.jinli.io/images/2024/09/19/black_myth_wukong.md.png)
A Small Issue
When playing games, I found that when the game plays a long cutscene, the monitor will display no input signal after about 30 seconds due to no operation. I suspect that it is caused by the power management mechanism of the graphics card. Running the xset -dpms
command can disable power management, which ensures that the display signal will not be interrupted.
With xset q
command, you can view the current power management settings, and with the xset
command, you can view the help information of the xset
command.