I just dropped my partner and my son off at the airport, so the dog and I are on our own for the next 10 days. This will give me plenty of time to do some reading (finishing up "Foundation and Empire" then starting on a Nixon biography that my friend Simon loaded me), some writing (part 2 of "Story of a mediocre fan" as well as on this here blog), and some exercising (tennis, running, swimming--that is as soon as my bloody rib stops hurting). Ah, improving the mind and body!
So naturally, as I'm eating breakfast, I get the bright idea to install Steam so I can play some Civ V. And since I'm on NixOS, this is gonna be easy, right?
Right?
At least I had the discipline to start my blog entry before trying to install Steam.
But here we go, installing Steam on NixOS in 50 simple steps!
[jmglov@laurana:~]$ nix repl '<nixpkgs>'
Welcome to Nix 2.8.1. Type :? for help.
Loading '<nixpkgs>'...
Added 16468 variables.
nix-repl> steam
error: Package ‘steam’ in /nix/var/nix/profiles/per-user/root/channels/nixos/pkgs/games/steam/steam.nix:43 has an unfree license (‘unfreeRedistributable’), refusing to evaluate.
Hell yeah! Don't worry about that unfree stuff; you've already got that sorted in your home.nix:nixpkgs.config.allowUnfree = true;
steam to home.packages, do a little searching and find an entry in the NixOS Wiki for Steam!home.nix:programs.steam = {
enable = true;
remotePlay.openFirewall = true; # Open ports in the firewall for Steam Remote Play
dedicatedServer.openFirewall = true; # Open ports in the firewall for Source Dedicated Server
};
[jmglov@laurana:/etc/nixos/jmglov]$ sudo nixos-rebuild switch
building Nix...
building the system configuration...
error: The option `home-manager.users.jmglov.programs.steam' does not exist. Definition values:
- In `/etc/nixos/configuration.nix':
{
dedicatedServer = {
openFirewall = true;
};
enable = true;
...
(use '--show-trace' to show detailed location information)
Oh you poor sweet child, thinking things would be that simple.programs.steam is a NixOS module, not a Home
Manager one. Grumble about having to install Steam system-wide, but then give in and move the Steam incantation to your /etc/nixos/configuration.nix, then rebuild NixOS:[jmglov@laurana:/etc/nixos/jmglov]$ sudo nixos-rebuild switch
building Nix...
building the system configuration...
these 47 derivations will be built:
/nix/store/0656idzgvxd6lsj5awhrami3wm66y1jk-ldconfig.drv
/nix/store/i99alh7g9xqb0dys5w8fklld15y2jjf9-steam-wrapper.sh.drv
/nix/store/0r8vhys80ipdspjch9l71ngddk62gws8-steam-init.drv
/nix/store/kik59lly3njfwdqni1vnhvgk1kmnsava-steam_1.0.0.74.tar.gz.drv
/nix/store/d9kgzf4khzvlzr1isbx49665b8xm2kma-steam-original-1.0.0.74.drv
# ...
building '/nix/store/6mzdfasrx16l5zbdks6qpn98fbgyvw15-nixos-system-laurana-22.05.751.8b66e3f2ebc.drv'...
updating GRUB 2 menu...
stopping the following units: accounts-daemon.service, systemd-modules-load.service, systemd-udevd-control.socket, systemd-udevd-kernel.socket, systemd-udevd.service
NOT restarting the following changed units: systemd-fsck@dev-disk-by\x2duuid-1495\x2d2D9B.service
activating the configuration...
setting up /etc...
reloading user units for jmglov...
setting up tmpfiles
reloading the following units: dbus.service, firewall.service
restarting the following units: polkit.service
starting the following units: accounts-daemon.service, systemd-modules-load.service, systemd-udevd-control.socket, systemd-udevd-kernel.socket
[jmglov@laurana:/etc/nixos/jmglov]$ steamcmd
steamcmd: command not found
home.nix (might as well install steam-tui, which you assume is some sort of UI?):home.packages = with pkgs; [
# ...
steam-tui
steamcmd
# ...
];
sudo nixos-rebuild switch to apply the changes, then quickly leave the room so you don't have to watch gcc warnings scroll by.steamcmd again:[jmglov@laurana:/etc/nixos/jmglov]$ steamcmd
bwrap: Can't chdir to /etc/nixos/jmglov: No such file or directory
WTF? Who told you to change to that directory, steamcmd?steamcmd script to see what in the ever-loving frack is going on around here:[jmglov@laurana:/etc/nixos/jmglov]$ cat $(which steamcmd)
#!/nix/store/40iwnlr30ykqm5ynm0bbk6bsjjc750ad-bash-5.1-p16/bin/bash -e
# Always run steamcmd in the user's Steam root.
STEAMROOT=~/.local/share/Steam
# Add coreutils to PATH for mkdir, ln and cp used below
PATH=$PATH${PATH:+:}/nix/store/2zxip96ccjx0nw24kfpjq3wl7kcx6035-coreutils-9.0/bin
# Create a facsimile Steam root if it doesn't exist.
if [ ! -e "$STEAMROOT" ]; then
mkdir -p "$STEAMROOT"/{appcache,config,logs,Steamapps/common}
mkdir -p ~/.steam
ln -sf "$STEAMROOT" ~/.steam/root
ln -sf "$STEAMROOT" ~/.steam/steam
fi
# Copy the system steamcmd install to the Steam root. If we don't do
# this, steamcmd assumes the path to `steamcmd` is the Steam root.
# Note that symlinks don't work here.
if [ ! -e "$STEAMROOT/steamcmd.sh" ]; then
mkdir -p "$STEAMROOT/linux32"
# steamcmd.sh will replace these on first use
cp /nix/store/4qbs47jafxn30v18kx6z8584s44g7djk-steamcmd-20180104/share/steamcmd/steamcmd.sh "$STEAMROOT/."
cp /nix/store/4qbs47jafxn30v18kx6z8584s44g7djk-steamcmd-20180104/share/steamcmd/linux32/* "$STEAMROOT/linux32/."
fi
/nix/store/vp2njgh5r7j7vs8691bp87apii754mna-steam-run/bin/steam-run "$STEAMROOT/steamcmd.sh" "$@"
21. Check out `$STEAMROOT` to see what's up:
```
[jmglov@laurana:/etc/nixos/jmglov]$ find ~/.local/share/Steam/
/home/jmglov/.local/share/Steam/
/home/jmglov/.local/share/Steam/steamcmd.sh
/home/jmglov/.local/share/Steam/logs
/home/jmglov/.local/share/Steam/appcache
/home/jmglov/.local/share/Steam/linux32
/home/jmglov/.local/share/Steam/linux32/libstdc++.so.6
/home/jmglov/.local/share/Steam/linux32/crashhandler.so
/home/jmglov/.local/share/Steam/linux32/steamerrorreporter
/home/jmglov/.local/share/Steam/linux32/steamcmd
/home/jmglov/.local/share/Steam/config
/home/jmglov/.local/share/Steam/Steamapps
/home/jmglov/.local/share/Steam/Steamapps/common
```
22. Scratch your cheek in that way people do that signifies deep puzzlement.
23. Have that "aha!" moment as you realise that obviously something weird is
happening in that `steamcmd.sh` script and then check it out:
``` bash
[jmglov@laurana:/etc/nixos/jmglov]$ cat /home/jmglov/.local/share/Steam/steamcmd.sh
#!/nix/store/40iwnlr30ykqm5ynm0bbk6bsjjc750ad-bash-5.1-p16/bin/bash
STEAMROOT="$(cd "${0%/*}" && echo $PWD)"
STEAMCMD=`basename "$0" .sh`
UNAME=`uname`
if [ "$UNAME" == "Linux" ]; then
STEAMEXE="${STEAMROOT}/linux32/${STEAMCMD}"
PLATFORM="linux32"
export LD_LIBRARY_PATH="$STEAMROOT/$PLATFORM:$LD_LIBRARY_PATH"
else # if [ "$UNAME" == "Darwin" ]; then
STEAMEXE="${STEAMROOT}/${STEAMCMD}"
if [ ! -x ${STEAMEXE} ]; then
STEAMEXE="${STEAMROOT}/Steam.AppBundle/Steam/Contents/MacOS/${STEAMCMD}"
fi
export DYLD_LIBRARY_PATH="$STEAMROOT:$DYLD_LIBRARY_PATH"
export DYLD_FRAMEWORK_PATH="$STEAMROOT:$DYLD_FRAMEWORK_PATH"
fi
ulimit -n 2048
MAGIC_RESTART_EXITCODE=42
if [ "$DEBUGGER" == "gdb" ] || [ "$DEBUGGER" == "cgdb" ]; then
ARGSFILE=$(mktemp $USER.steam.gdb.XXXX)
# Set the LD_PRELOAD varname in the debugger, and unset the global version.
if [ "$LD_PRELOAD" ]; then
echo set env LD_PRELOAD=$LD_PRELOAD >> "$ARGSFILE"
echo show env LD_PRELOAD >> "$ARGSFILE"
unset LD_PRELOAD
fi
$DEBUGGER -x "$ARGSFILE" "$STEAMEXE" "$@"
rm "$ARGSFILE"
else
$DEBUGGER "$STEAMEXE" "$@"
fi
STATUS=$?
if [ $STATUS -eq $MAGIC_RESTART_EXITCODE ]; then
exec "$0" "$@"
fi
exit $STATUS
```
24. Spend some time scratching your head, because that cheek thing apparently
didn't cut it.
25. Have a look at `/run/current-system/sw/bin/steam-run`, then scratch your
head some more.
26. Realise that `/etc/nixos/jmglov` is where you keep your Home Manager config,
then guess that since you're installing Steam as an os-wide package, maybe
you should do the same with `steamcmd` and `steam-tui`.
27. Realise that blergh! the channel being used by Home Manager is probably not
the same one being used by NixOS.
28. Confirm this:
```
[jmglov@laurana:/etc/nixos/jmglov]$ nix-channel --list
home-manager https://github.com/nix-community/home-manager/archive/release-21.05.tar.gz
nixos https://nixos.org/channels/nixos-21.11
unstable https://nixos.org/channels/nixpkgs-unstable
```
29. Swear in whatever way you see fit.
30. Promise yourself to upgrade Home Manager to 21.11 someday (but not this
day).
31. Move the bloody packages to bloody `/etc/nixos/configuration.nix` and `sudo
nixos-rebuild switch` again.
32. Hold your breath and try `steamcmd` again:
```
[jmglov@laurana:/etc/nixos/jmglov]$ steamcmd
bwrap: Can't chdir to /etc/nixos/jmglov: No such file or directory
```
33. Swear at greater length than you previously did.
34. Realise something about your prompt and slowly turn red with embarrassment.
35. Type a command so your readers can see why you're embarrassed if they didn't
already catch it somewhere around step 19:
```
[jmglov@laurana:/etc/nixos/jmglov]$ pwd
/etc/nixos/jmglov
```
36. Change to your actual home directory obv.
37. Run `steamcmd` and watch as stuff actually happens!
```
[jmglov@laurana:~]$ steamcmd
Redirecting stderr to '/home/jmglov/.local/share/Steam/logs/stderr.txt'
ILocalize::AddFile() failed to load file "public/steambootstrapper_english.txt".
[ 0%] Checking for available update...
[----] Downloading update (0 of 54,952 KB)...
[ 0%] Downloading update (642 of 54,952 KB)...
[ 1%] Downloading update (1,326 of 54,952 KB)...
[ 2%] Downloading update (2,236 of 54,952 KB)...
...
[----] Installing update...
[----] Cleaning up...
[----] Update complete, launching Steamcmd...
Redirecting stderr to '/home/jmglov/.local/share/Steam/logs/stderr.txt'
[ 0%] Checking for available updates...
[----] Verifying installation...
Steam Console Client (c) Valve Corporation - version 1654574676
-- type 'quit' to exit --
Loading Steam API...OK
Steam>
```
38. Swear again, but this time in celebration of the great victory you just
achieved!
39. Login to Steam, as soon as you remember your username and password:
```
Steam>login jmglov "This is not actually a password; nice try!"
Logging in user 'jmglov' to Steam Public...
This computer has not been authenticated for your account using Steam Guard.
Please check your email for the message from Steam, and enter the Steam Guard
code from that message.
You can also enter this code at any time using 'set_steam_guard_code'
at the console.
Steam Guard code:H4X0R
OK
Waiting for client config...OK
Waiting for user info...OK
```
40. Get distracted by an email from your new boss whilst you're looking for your
Steam Guard code. Reply, because that's your boss writing!
41. According to the [NixOS Wiki article](https://nixos.wiki/wiki/Steam),
`steam-tui` "should start just fine" after logging into Steam using
`steamcmd`, so give it a whirl!
42. Realise that `steam-tui` obviously stands for Steam Terminal User Interface,
and get a little sad that you're not looking at the awesome Steam UI that
they have on standard Linux.
43. Press on and login.
44. OMG check out your games menu! They're all there (plus some ones that your
son apparently bought on your account; hrm, gonna have to talk to that dude
when he gets back from Bulgaria).
45. Realise that `steam-tui` won't let you select text on your terminal to paste
here, so you'll need to take a screenshot.
46. Research a screenshot utility, discover [Xfce](https://xfce.org/) comes with
one, and add some stuff to your [i3](https://i3wm.org/) config to bind the
appropriate keys:
```
# You gotta have screenshots!
bindsym Print exec xfce4-screenshooter -f
bindsym Shift+Print exec xfce4-screenshooter -r
bindsym Control+Print exec xfce4-screenshooter -w
```
47. Take a screenshot and put it in the appropriate place to show up on your
blog as soon as you fix the Markdown rendering of images.
48. Leave a placeholder here to display your games menu (and ask yourself if it
was really worth it): 
49. Try to download Sid Meier's Civilization V and tug on your chin in
puzzlement as nothing seems to happen. Oh wait! Now the state has changed
from "uninstalled" to "Update Required".
50. Realise it's nearly lunchtime and ragequit `steam-tui` and this blog post!
## Update from 2022-07-09
It turns out that I was missing something incredibly simple. Thanks to an
article entitled "[How to Install Steam on
NixOS?](https://linuxhint.com/how-to-instal-steam-on-nixos/)", I realised that
the Steam module that I installed by adding `programs.steam.enable = true;` to
my `/etc/nixos/configuration.nix` installed the `steam` executable, which is the
official Steam client for Linux. Starting that (from my home directory, as I
discovered in steps 19-36) updated the client to the latest version, then I
could browse to my library and install Civ V. Hurrah!
![Screenshot of my Steam library, with Civ V finally downloading][steam]
There was of course one last hurdle before I could actually play. When I clicked
the play button, nothing seemed to happen, until I looked at the terminal window
where I had run `steam` and saw some helpful errors:
/bin/sh\0-c\0/home/jmglov/.local/share/Steam/ubuntu12_32/reaper SteamLaunch AppId=8930 -- '/home/jmglov/.local/share/Steam/steamapps/common/Sid Meier'''s Civilization V/./Civ5XP'\0 Game process added : AppID 8930 "/home/jmglov/.local/share/Steam/ubuntu12_32/reaper SteamLaunch AppId=8930 -- '/home/jmglov/.local/share/Steam/steamapps/common/Sid Meier'''s Civilization V/./Civ5XP'", ProcID 600547, IP 0.0.0.0:0 SpawnProcessInternal: chdir /home/jmglov/.local/share/Steam/steamapps/common/Sid Meier's Civilization V failed, errno 2
It turned out that there was both a `~/.local/share/Steam/steamapps` and
a `~/.local/share/Steam/Steamapps` directory, and of course the Steam client was
looking in little-s `steamapps`, and Civ V was installed in big-S `Steamapps`.
🤦🏼
Ah well, easy enough to fix:
cd ~/.local/share/Steam/steamapps/common ln -s ../../Steamapps/common/Sid\ Meier's\ Civilization\ V
And Robert is indeed your mother's brother.
![Screenshot of the Civ V opening screen, playing as Darius I of Persia][civ]
[steam]: assets/2022-07-09-steam-library.png "Let's get it on!{ATTRS:
[civ]: assets/2022-07-09-civ-v.png "Civilise this!"}"