NixOS / nixpkgs

Nix Packages collection & NixOS
MIT License
16.49k stars 12.99k forks source link

SteamPlay Compatibility Tools: Proton-GE, Boxtron, Roberta, Luxtorpeda #73323

Open ghost opened 4 years ago

ghost commented 4 years ago

Project description As many of you already know, Steam has a built in compatibility tool for playing Windows games on Linux called Proton. In addition there's several other compatibility tools that have been made by the community.

Recently Steam has officially added the ability for distributions to package their own compatibility tools: https://github.com/ValveSoftware/steam-for-linux/issues/6310

I propose packaging the following known projects:

Some of the projects listed above have NixOS specific issues, for example: https://github.com/dreamer/roberta/issues/6

stale[bot] commented 3 years ago

I marked this as stale due to inactivity. → More info

yusdacra commented 3 years ago

Still important to me

kira-bruneau commented 3 years ago

I think steam hard-codes the global compatibility tool search paths to /usr/share/steam/compatibilitytools.d & /usr/local/share/steam/compatibilitytools.d, but also allows configuration with STEAM_EXTRA_COMPAT_TOOLS_PATHS: https://github.com/ValveSoftware/steam-for-linux/issues/6310#issuecomment-511630263.

If steam doesn't follow the XDG Base Directory specification (which seems very likely), then we will have to emulate it through a wrapper that defines STEAM_EXTRA_COMPAT_TOOLS_PATHS. Without this, steam won't pick up Nix-installed compatibility tools.

This would also need to be patched in protontricks: https://github.com/Matoking/protontricks/blob/1.5.1/src/protontricks/steam.py#L625-L641

stale[bot] commented 2 years ago

I marked this as stale due to inactivity. → More info

TheOddler commented 2 years ago

No stale bot, I'd like to keep this fresh a bit longer. Still important to me.

alisonjenkins commented 2 years ago

This is also something I am interested in. I would have a go at creating this myself but I do not yet have a proper grasp on how to make my own derivations.

benneti commented 2 years ago

Assuming you use nvfetcher and home-manager it is reasonably straight forward to have a semi automatic process: nvfetcher sources.toml

[luxtorpeda]
src.github = "luxtorpeda-dev/luxtorpeda"
src.from_pattern = "v(\\d*)"
src.to_pattern = "\\1"
fetch.url = "https://github.com/luxtorpeda-dev/luxtorpeda/releases/download/v$ver/luxtorpeda-$ver.tar.xz"

[proton-ge]
src.github = "GloriousEggroll/proton-ge-custom"
fetch.url = "https://github.com/GloriousEggroll/proton-ge-custom/releases/download/$ver/Proton-$ver.tar.gz"

then you can have simple derivations for those releases

{ lib, stdenv, sources }:
stdenv.mkDerivation rec {
  inherit (sources.luxtorpeda) pname src version;

  nativeBuildInputs = [ ];

  installPhase = ''
    mkdir -p $out
    mv * $out/
  '';
}

and the same for proton-ge and to automatically put them in the correct folder you can use

  # proton is very large and slows down the boot when linking, therefore only copy the files when necessary
  home.activation = lib.mkIf global-config.programs.steam.enable
    {
      proton-ge = (lib.hm.dag.entryAfter [ "writeBoundary" ] ''
        target="${xdgData}/Steam/compatibilitytools.d/Proton-${pkgs.proton-ge.version}"
        if ! [ -d "$target" ]; then
          cp -R ${pkgs.proton-ge} "$target"
          chmod -R u+w "$target" # not strictly necessary...
        fi
      '');
    };

  # luxtorpeda has another kind of versioning and is much smaller we can safely link it
  xdg.dataFile = lib.mkIf global-config.programs.steam.enable {
    luxtorpeda = {
      recursive = true;
      source = "${pkgs.luxtorpeda}";
      target = "Steam/compatibilitytools.d/luxtorpeda";
    };
  };

in you home-manager configuration. In total this puts the prebuilt releases in the correct place for steam to detect and thanks to the steam-run environment they simply work. For nixpkgs I think this solution is not suitable at all but for a selfrolled config it fits the bill.

Shawn8901 commented 2 years ago

Hi there, As i was searching a solution for me to have proton-ge available on my machine i stumbled over this issue. The solution @benneti presented looked quite strait forward for me, nevertheless i am still learning a lot of stuff how to handle things in nix.

So i did just create a derivation without the sources.toml which looks basically like this

{ stdenv, lib, fetchurl }:

stdenv.mkDerivation rec {
  pname = "proton-ge-custom";
  version = "GE-Proton7-10";

  src = fetchurl {
    url = "https://github.com/GloriousEggroll/proton-ge-custom/releases/download/${version}/${version}.tar.gz";
    sha256 = "rpvWeYq7IZNcpg0VQTDpT3nX79YvK8MemO8dIj0j9UQ=";
  };

  buildCommand = ''
    mkdir -p $out
    tar -C $out --strip=1 -x -f $src
  '';
}

Then I set STEAM_EXTRA_COMPAT_TOOLS_PATHS as environment variable like this in my chase with HomeManager

  home.sessionVariables = {
    STEAM_EXTRA_COMPAT_TOOLS_PATHS = "${pkgs.proton-ge-custom}";
  };

After relogin to have the variables applied, go to steam settings and the custom runtime is visible in the dropdown. I have atm just tested to start a random game which i know should work (Rocket League in that case), and i could not see any issues.

As i am grabbing a prebuild version in the derivation (compiling proton-ge-custom looks quite complicated, got it running to apply patches at some point, but some the patches thrown errors and also newer versions try to use docker or podman for some steps, which i did not yet solved, but archlinuxs aur packages has some patches to disable that, but something for later), and which does not look very desired for me as the source code is available. I dont think that this state should go to any repository, but maybe its helping someone.

pmarreck commented 1 year ago

Thanks to @kira-bruneau 's tip about having to set the STEAM_EXTRA_COMPAT_TOOLS_PATHS environment variable in my config (for noobs: under environment.variables), my Steam on NixOS can finally see my Proton-GE, lol. Thanks!

One note, does it need to be an absolute path? (i.e., is it resolved at boot time, or after $HOME is set?) Ideally I'd like it to be relative to the logged-in user's home directory.

(Ah. I just realized that home-manager would basically solve this problem out of the box. Haven't set that up yet.) (Or literally what @Shawn8901 just said, which I just noticed. Whoops.)

Maybe the same source code in nix that does all the magic when you simply set programs.steam.enable = true should also set this environment variable to $HOME/.steam/root/compatibilitytools.d for now? (Resolving $HOME in a declarative way that is not dependent on the logged-in user, perhaps by deferring evaluation until an interactive session (sessionVariables?) happens, would be tricky, I guess)

EDIT: Oooh, this is doable: https://nixos.wiki/wiki/Environment_variables

camtauxe commented 1 year ago

@Shawn8901's solution very nearly worked for me. In my case, Steam wasn't aware of environment variables set through home-manager's home.sessionVariables option, but setting STEAM_EXTRA_COMPAT_TOOLS_PATHS through NixOS's environmnet.variables option did the trick!

romatthe commented 1 year ago

I don't know if this is possible, but it would be really cool if the NixOS Steam module could support this out of the box, something along the lines of:

programs.steam = {
    enable = true;
    remotePlay.openFirewall = true;
    extraCompatPackages = with pkgs; [
        boxtron
        luxtorpeda
        proton-ge
    ];
};

Which would then populate STEAM_EXTRA_COMPAT_TOOLS_PATHS system wide with ${boxtron};${luxtorpeda};${proton-ge} etc etc.

Unfortunately I'm not familiar enough with modules and the trickier nix stuff to know if this is feasible or how to do it. I mean, just putting a simple line to fix the environmental variables underneath it is easy enough, but it would be nice if a solution like this could be provided out of the box for people not in the know.

kira-bruneau commented 1 year ago

I don't know if this is possible, but it would be really cool if the NixOS Steam module could support this out of the box

Oh that would be neat, it definitely is possible! We could have it set STEAM_EXTRA_COMPAT_TOOLS_PATHS... or I was originally thinking of creating a wrapper around steam that would derive STEAM_EXTRA_COMPAT_TOOLS_PATHS using the XDG Base Directory Specification.

That way, tools can be installed system-wide to /run/current-system/sw/share/steam/compatibilitytools.d (through environment.systemPackages) or configured at runtime with XDG_DATA_DIRS

Steam already looks for files in ~/.local/share/steam/compatibilitytools.d, so we wouldn't need to include that in STEAM_EXTRA_COMPAT_TOOLS_PATHS (unless XDG_DATA_HOME is set).

(Just an idea though. I haven't actually used steam in almost a year, and probably wouldn't get around to doing this myself any time soon).

romatthe commented 1 year ago

I was originally thinking of creating a wrapper around steam that would derive STEAM_EXTRA_COMPAT_TOOLS_PATHS using the XDG Base Directory Specification.

That also sounds like an interesting idea!

romatthe commented 1 year ago

I've made a quick PR of my initial idea here #189398, any feedback or input is appreciated of course. It's probably a little rough around the edges and could use a more robust solution.

Shawn8901 commented 1 year ago

I've made a quick PR of my initial idea here #189398, any feedback or input is appreciated of course. It's probably a little rough around the edges and could use a more robust solution.

I really like that you catched up the idea on setting those as variable and include that to the steam module. i have left a small comment, as i find that you are a bit restrictive on the pkg structure. Beside that great job, that should improve the usability on custom proton builds there a lot. :smile:

crertel commented 1 year ago

This is all really cool work! Out of curiosity, are there any updates?

pmarreck commented 1 year ago

I'll be honest, if I had the time I'd love to help work on NixOS's "native" steam implementation and related pieces like Proton, Proton-GE etc., but when I last looked at it a few months ago, I ran into issues with various games (in particular, as I recall, any games that used Unity engine, but other types of games as well); as I have a 19 month old son which has vacuumed up all available time, in order to "just get it working" for the hour or so of precious free time I have every day, I've resorted to installing it via Flatpak, where it's worked pretty flawlessly (it also lets you install Proton and other popular linux steam tools), the only catch is that you have to update Steam via Flatpak and reboot whenever you get a GPU driver update or your games will appear to stop working, which confused me for a while.

This is definitely (IMHO) a subpar and temporary solution (seriously, using Flatpak on NixOS is like using a BlackBerry app store on an iPhone!), but I can say that it works, if you prefer NixOS but want your occasional game sesh without too much hassle. Pretty much 100% of my game library works now, it's been pretty amazing what the Steam Deck has done for Linux gaming actually.

FYI, it's possible to bind-mount the 2 different Steam directories created by Native Steam/Flatpak Steam which might enable you to share your library between them (necessitating possibly only a re-login if you switch clients) and avoid having to re-download all your content.

I'm curious as to what other "nixos gamers" are doing.

aanderse commented 1 year ago

I'm curious as to what other "nixos gamers" are doing.

Family of five here, all gamers, though mostly casual. In 6 years of using NixOS as a gaming rig haven't had any real issues the entire time. Whenever I see issues come up on related to steam I often wonder what I'm doing "wrong" because gaming on NixOS with steam "just works" for my family and I. :man_shrugging:

it's been pretty amazing what the Steam Deck has done for Linux gaming actually.

Yes! Absolutely awesome how the entire LEGO collection of games works flawlessly on Linux now. :smile:

Shawn8901 commented 1 year ago

i am still using this a custom module on my system, which is basically an implementation like https://github.com/NixOS/nixpkgs/pull/189398 but without any modifications on the steam module (i dont want to override it), which is working without any issues for me. As addition i have a package that provides me a proton-ge that can be found here. The combination of both is working quite solid. The only thing that does sometimes annoy me, steam does not like it, if STEAM_EXTRA_COMPAT_TOOLS_PATHS changes, then i have to reselect the proton runtime inside steam.

GrabbenD commented 1 year ago

Thanks a lot @Shawn8901!!

I'm not sure if this is the best approach since I'm new to NixOS but this is how I encapsulated your configuration outside of Flakes:

{ pkgs, ... }: let
  flake-compat = builtins.fetchTarball "https://github.com/edolstra/flake-compat/archive/master.tar.gz";
  proton-overlay = (import flake-compat {
    src = builtins.fetchTarball "https://github.com/Shawn8901/nix-configuration/archive/master.tar.gz";
  }).defaultNix;
in {
  imports = [
    "${proton-overlay}/modules/nixos/steam-compat-tools.nix"
  ];

  programs.steam = {
    enable = true;
    extraCompatPackages = with pkgs; [
      proton-overlay.packages.${pkgs.hostPlatform.system}.proton-ge-custom
    ];
  };
}
Shawn8901 commented 1 year ago

I don't know if you want to rely on my module, of course you can technically, but I may break your config by accident if I change something on my config. I would recommend to just copy that, make it import it as a module (like you import mine) and then you do not have to play around with flakes. If you want to keep a reference to my config and/or to this issue, in case you want to revisit it later.

Technical wise you are doing everything okay (beside that i should properly export the module, so that it gets more usable). ~If you really want to depend on my config, i should change my flake in a way that i export those modules explicitly, so that I can still move it around. If you prefer that please let me know.~

edit: i am now exposing that module now properly anyways. so you should now be able to import it as instead referencing my structure as path

  imports = [
    proton-overlay.nixosModules.steam-compat-tools
  ];

Let me know if that does not work.

PS: the proton package gets autoupdated by a Github action, so you may have to reselect that after updates in steam.

PedroHLC commented 1 year ago

I've added Shawn8901 module and package to https://github.com/chaotic-cx/nyx, also added Luxtorpeda. But just as a temporary and easy-to-use solution before someone merges it to nixpkgs.

nixos-discourse commented 1 year ago

This issue has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/what-would-it-take-to-package-proton-tkg/13075/5

GrabbenD commented 1 year ago

I may break your config by accident if I change something on my config. I would recommend to just copy that, make it import it as a module (like you import mine) and then you do not have to play around with flakes. If you want to keep a reference to my config and/or to this issue, in case you want to revisit it later.

That's always a risk when using someone's code 😄 If you never change your username or delete the repository, the code can be pinned to avoid breakage when you move things around:

{
  proton-overlay = (import flake-compat {
    src = builtins.fetchTarball "https://github.com/Shawn8901/nix-configuration/archive/89235ff5f3eb7f3efbea300ce745807044dd12c4.tar.gz";
  }).defaultNix;
}

i am now exposing that module now properly anyways. so you should now be able to import it as instead referencing my structure as path

This's highly appreciated, thanks for taking the time to do it!

Shawn8901 commented 1 year ago

Just as hint, as you are also referencing the proton package from my flake, pinning it to a commit will result in not getting updates anyloger.

GrabbenD commented 1 year ago

PS: the proton package gets autoupdated by a Github action, so you may have to reselect that after updates in steam.

Just updated NixOS channel and I can no longer select GE-Proton-7-55 in compatibility tab in due to:

Proton: Prefix has an invalid version?! You may want to back up user files and delete this prefix.

What's the correct way of fixing this in Nix?

Shawn8901 commented 1 year ago

I personally are not even sure what the issue is and how to fix it in anon-nox way. When googling around i found a similar thing when using mangohub (or how it was called) when activating it via global variables. But that's just a super blind guess. I'll check on the weekend if my setup still works.

I assume that you found that log line in the journal? And.i assume that you are on nixos-unstable?

Edit: i can not reproduce the issue with the given information. sorry