Featured image of post Linux System: Share Steam Games Among Multiple Users (Ubuntu as an Example)

Linux System: Share Steam Games Among Multiple Users (Ubuntu as an Example)

Share Steam games among multiple users on Linux system to avoid redownloading

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.

OS Requirements

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

  1. Download the Steam installation package:
1
wget https://cdn.cloudflare.steamstatic.com/client/installer/steam.deb
  1. Install Steam:
1
sudo dpkg -i steam.deb
  1. Install missing dependencies:
1
sudo apt-get install -f
  1. Run Steam:
1
steam
  1. Log in to your Steam account

Steam

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.

Dota 2

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

  1. 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
    
  2. Switch to the user2 user:

    Click the user icon in the upper right corner of the screen, select Switch Account, and then select the user2 user to log in.

  3. Open and log in to Steam:

    After opening the Steam client, Steam will create a .steam directory in the home directory of the user2 user, but the .steam/steam/steamapps directory of the user2 user does not contain game files. Therefore, when you click the Library page, you will find that the library does not show the games downloaded by the user1 user.

    Next, we will mainly solve this problem, allowing the user2 user to access the game files downloaded by the user1 user and run the games normally.

Share Game Files

  1. 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
    
  2. 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 to 755:

    1
    
    sudo chmod 755 /opt/games/steam
    

    Then we create a new user group steam and add the user1 and user2 users to this user group:

    1
    2
    3
    
    sudo groupadd steam
    sudo usermod -aG steam user1
    sudo usermod -aG steam user2
    

    Finally, we set the user group of the /opt/games/steam directory to steam:

    1
    
    sudo chown -R user1:steam /opt/games/steam
    
  3. 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 the user1 user:

    1
    
    ln -s /opt/games/steam/steamapps /home/user1/.steam/steam/steamapps
    

    Then we open the Steam client under user1, click the Library 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.

  4. Similarly for the user2 user, we need to create a symbolic link in the home directory of the user2 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 the Library 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 select Properties, click Verify Integrity in the Local Files tab, and you will find that the integrity check fails.

  5. The above problem is quite strange, because we have set the permissions of the /opt/games/steam directory to 755, and added the user1 and user2 users to the steam user group, but the error message above indicates that the Steam client under the user2 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:

    These discussions mainly propose two solutions:

    1. 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.

    2. 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

  1. 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
    
  2. 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
    
  3. 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 the CompatData class. We need to modify the line self.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.

  4. 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 require sudo 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
      
  5. After the compilation is completed, we create the installation files of Proton:

    1
    
    make redist
    

    This way, a redist directory will be generated in the build directory, which contains the installation files of Proton.

  6. Install Proton. For user-defined compatibility layers, we can place them in the ~/.steam/root/compatibilitytools.d/ directory. We copy the redist 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 the user_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)
  1. 安装Proton。对于用户自定义的兼容层,我们可以将其放在~/.steam/root/compatibilitytools.d/目录下。我们将redist目录整体复制到~/.steam/root/compatibilitytools.d/目录下:

    1
    
    cp -r redist ~/.steam/root/compatibilitytools.d/myfeature-9.0-pr4861
    

    注意,不管在哪个账号下使用Steam,我们都需要把redist目录复制到~/.steam/root/compatibilitytools.d/目录下,并修改目录的所有权为当前用户。例如如果是user_x用户,我们可以这样:

    1
    
    sudo chown -R user_x:user_x ~/.steam/root/compatibilitytools.d/myfeature-9.0-pr4861
    
comments powered by Disqus