Blog: Gaming on Alpine Linux
Posted: Sun Jun 09, 2024 1:08 pm
Today I decided to do something productive with my Sunday: After casting my vote in the morning, I decided to get rid of the last Windows installation in my possession.
I have a laptop I use for web (mostly Youtube), e-mail, and development. It's been running Linux since I got it. I also have a PC I use for gaming. Until today, it was running Windows (first 10, then 11). But with Microsoft getting increasingly desperate to squeeze blood from the stone that is Windows, and turning to the dark AI arts to do it (not so long ago, Windows Recall would have been classed as spyware, plain and simple), I decided to get rid of it by installing Linux. And not just any Linux, but Alpine Linux.
I do realize I set myself up for failure here. Not only using the less popular platform, but foregoing glibc, and with it binary compatibility to what few games are supported natively. But I did make it work, for now. It doesn't work very well, but good enough for my purposes. Also, as a Debian user of 20 years, using something completely different definitely was a new experience for me. I keep typing "apt" when I mean "apk", and when running a command as root, my fingers instinctively seek out the s and u keys, before remembering that "sudo" is now "doas". Force of habit. Hopefully after today, I won't be needing that many root commands anymore, though.
Installation was surprisingly painless, though the Alpine installer is nothing for people that break out in hives at the sight of a console. Remember the old Debian installer, before they had the ncurses one? That is pretty much the Alpine installer. But it also has some features Debian is sorely lacking: When being asked to select a package mirror to use (a question you basically have to answer with zero context), you have the option to select the fastest one. That verifies that your internet connection is working, and filters out completely non-working ones as well.
After installation I finally figured out how to make the BIOS boot from M.2 drive. There is a boot order list in the BIOS, but that did not contain the M.2 drive, so there was no way for me to put it up at the top of the list. Turns out that MSI was just being difficult: The boot order list contains only one entry for each type of drive, and further down you can select which drive is meant for each given type. So in the boot order, I had to put "UEFI Harddisk" at the top, then further down select the M.2 drive as the option for "UEFI Harddisk". Why the indirection? Because they could, I suppose.
Anyway, I wasn't done doing things the hard way. The base system install has no graphics system, so I decided to install Wayland. That was the first time for me. On my laptop, I am happily using Xorg and awesome. But Wayland is the future, so best to rip the band-aid off in one go. I would have used Hyprland, but Alpine has no package for it, so now I am using sway for the time being. The Alpine wiki makes reference to loading the right graphics modules and stuff, but apparently that is not necessary, as the kernel auto-detects the hardware and loads modules accordingly. I had never really used an AMD GPU on Linux before, so when the Wiki said to just pick "radeon" or "amdgpu" as driver, I was a bit stumped. Turned out not to matter for the above reason, but apparently "amdgpu" is the right one.
Also, when sway reports an error from the amdgpu driver about how it could not create some sort of context, that error message does not matter. Always helpful to have error messages that don't matter.
The Wiki wanted me to install a greeter. After much back and forth, I had something working, but found that I could not log in. The reason being that my password contains a y, and I have a German keyboard. And if there is a way to set the keyboard layout generally for all Wayland compositors, I could not find it, but they default to American layout. I did set the layout in sway, but the greeter ran under cage, and there was no documentation for changing the keyboard layout in cage.
In the end, I decided to get rid of the greeter. I login with agetty on the command line, then start the graphics server, like it was 1995. Only the graphics server is now called sway instead of xinit.
Next issue was sound. Apparently, the current hotness is "pipewire". I had only ever vaguely heard about it, and I suppose something must throw a spanner in the works every now and again. After following the Wiki directions, I now have a system that works, but only in sway under dbus. I'm not a big fan of this bundling (why are graphics and sound now entwined?), but apparently it must be done, because pipewire depends on dbus, and I'm not starting dbus twice! The setup I have now works, but only once per boot. Thankfully I rarely log off the system without shutting it down entirely.
Finally, the games. I decided to go with Steam (obviously). However, the Wiki instructions were somewhat false. It was necessary for me to install Steam in the system flatpak repository along with the user one, because otherwise there would be an error on startup. After doing that, it was possible for me to log in, but I did find that my gamepad was not recognized. That was because even though I had installed the steam-devices package, my user still had to be in the "input" group for SDL to recognize the input devices. God only knows how the compositors kept reading those event files!
My first test case was Solar Ash, a Windows game with no Linux support. Running it under Proton worked pretty much immediately, once the input file kerfuffle was sorted. And the game ran about as well as it did on Windows.
Next test case was EXAPUNKS, a native Linux puzzle game. That one turned out to be much harder, actually. I could start the game, but it would always crash after a couple of seconds. So it was time for me to get the debugger out. And the debugger I used was the only real debugger: strace. Unlike all the others, it does not try to misrepresent reality by claiming that C was BASIC, but rather, it only displays what syscalls the processes are making, and what the results are.
Using strace, I determined that the game was writing a crash report to /tmp. But I could not find it there. After much back and forth, it turns out that Steam does some black magic with mount namespaces and cgroups, and what EXAPUNKS saw as /tmp was actually $XDG_RUNTIME_DIRECTORY/<some longer path here>/tmp. Maybe there was also something going on with bind mounts. Anyway, there was an error message about dbus not containing the OpenURI function, so I was hoping that if I could provide that function, then the crash information would be displayed to me in firefox. That never happened!
First, OpenURI is contained in the XDG GTK portal, so I had to install the package xdg-desktop-portal-gtk. But that one by default provides OpenURI only to GNOME. I am using sway. I had to create an obscure config file to make it work, and then reboot the system. And even then, no crash report, but the error message about the non-existant OpenURI was now gone.
It turned out that EXAPUNKS was crashing and writing a crash log to /tmp/burduke-crash-log.html, then calling "xdg-open /tmp/burduke-crash-log.html". xdg-open would find the file under that name and run the OpenURI function through dbus. But dbus would escape the sandbox Steam had made, and the file name would not be translated, so by the time it reached Firefox, the file could no longer be found (because of the aforementioned mount namespace trickery), and Firefox would just decide to do - nothing. Lovely.
Once I had the file name, though, I could search for the file, and I did find it. And then I looked at it, and the reason it crashed was that the type "System.Console" could not be created.
See, EXAPUNKS was written in C#. And on Linux, it is executed under Mono, of course. And apparently someone at Mono needs to get a kick in the arse. It turns out that if the TERM variable is set to a string the system doesn't have the terminfo for, then Mono will fail creating the System.Console type, with either the exception "There was an exception creating the type "System.Console"", or sometimes the exception is even printed, and then it is a chain of things resulting finally in "Exception: Bad magic number 542." This despite the fact, that in the overwhelming majority of cases, System.Console is only used to print simple strings, and that works the same on all terminals. And because I was using Wayland, my terminal emulator was now called "foot". The terminfo for "foot" was in my local terminfo database, of course, but flatpaks run in their own environments I can't change, and I have no idea how I should do so.
So, closing Steam and restarting it setting TERM=xterm allowed me to get further. Modifying EXAPUNKS' loader script to also set TERM=xterm (because it somehow got reverted when starting the game in Steam) finally allowed the game to work. What was the message printed to the terminal, that was so important it had to crash the application? "The key could not be found in the dictionary", printed 50 times. Not saying what key or what dictionary. Apparently it was read on some kind of timer after starting the game.
There you have it. Gaming is definitely possible on Linux, even with distributions that are definitely not meant for it. Next step for me is going to be to actually start using the two hard disks I have in the system, as additional storage. I have an LVM tutorial queued up already. I'll see how it goes.
I have a laptop I use for web (mostly Youtube), e-mail, and development. It's been running Linux since I got it. I also have a PC I use for gaming. Until today, it was running Windows (first 10, then 11). But with Microsoft getting increasingly desperate to squeeze blood from the stone that is Windows, and turning to the dark AI arts to do it (not so long ago, Windows Recall would have been classed as spyware, plain and simple), I decided to get rid of it by installing Linux. And not just any Linux, but Alpine Linux.
I do realize I set myself up for failure here. Not only using the less popular platform, but foregoing glibc, and with it binary compatibility to what few games are supported natively. But I did make it work, for now. It doesn't work very well, but good enough for my purposes. Also, as a Debian user of 20 years, using something completely different definitely was a new experience for me. I keep typing "apt" when I mean "apk", and when running a command as root, my fingers instinctively seek out the s and u keys, before remembering that "sudo" is now "doas". Force of habit. Hopefully after today, I won't be needing that many root commands anymore, though.
Installation was surprisingly painless, though the Alpine installer is nothing for people that break out in hives at the sight of a console. Remember the old Debian installer, before they had the ncurses one? That is pretty much the Alpine installer. But it also has some features Debian is sorely lacking: When being asked to select a package mirror to use (a question you basically have to answer with zero context), you have the option to select the fastest one. That verifies that your internet connection is working, and filters out completely non-working ones as well.
After installation I finally figured out how to make the BIOS boot from M.2 drive. There is a boot order list in the BIOS, but that did not contain the M.2 drive, so there was no way for me to put it up at the top of the list. Turns out that MSI was just being difficult: The boot order list contains only one entry for each type of drive, and further down you can select which drive is meant for each given type. So in the boot order, I had to put "UEFI Harddisk" at the top, then further down select the M.2 drive as the option for "UEFI Harddisk". Why the indirection? Because they could, I suppose.
Anyway, I wasn't done doing things the hard way. The base system install has no graphics system, so I decided to install Wayland. That was the first time for me. On my laptop, I am happily using Xorg and awesome. But Wayland is the future, so best to rip the band-aid off in one go. I would have used Hyprland, but Alpine has no package for it, so now I am using sway for the time being. The Alpine wiki makes reference to loading the right graphics modules and stuff, but apparently that is not necessary, as the kernel auto-detects the hardware and loads modules accordingly. I had never really used an AMD GPU on Linux before, so when the Wiki said to just pick "radeon" or "amdgpu" as driver, I was a bit stumped. Turned out not to matter for the above reason, but apparently "amdgpu" is the right one.
Also, when sway reports an error from the amdgpu driver about how it could not create some sort of context, that error message does not matter. Always helpful to have error messages that don't matter.
The Wiki wanted me to install a greeter. After much back and forth, I had something working, but found that I could not log in. The reason being that my password contains a y, and I have a German keyboard. And if there is a way to set the keyboard layout generally for all Wayland compositors, I could not find it, but they default to American layout. I did set the layout in sway, but the greeter ran under cage, and there was no documentation for changing the keyboard layout in cage.
In the end, I decided to get rid of the greeter. I login with agetty on the command line, then start the graphics server, like it was 1995. Only the graphics server is now called sway instead of xinit.
Next issue was sound. Apparently, the current hotness is "pipewire". I had only ever vaguely heard about it, and I suppose something must throw a spanner in the works every now and again. After following the Wiki directions, I now have a system that works, but only in sway under dbus. I'm not a big fan of this bundling (why are graphics and sound now entwined?), but apparently it must be done, because pipewire depends on dbus, and I'm not starting dbus twice! The setup I have now works, but only once per boot. Thankfully I rarely log off the system without shutting it down entirely.
Finally, the games. I decided to go with Steam (obviously). However, the Wiki instructions were somewhat false. It was necessary for me to install Steam in the system flatpak repository along with the user one, because otherwise there would be an error on startup. After doing that, it was possible for me to log in, but I did find that my gamepad was not recognized. That was because even though I had installed the steam-devices package, my user still had to be in the "input" group for SDL to recognize the input devices. God only knows how the compositors kept reading those event files!
My first test case was Solar Ash, a Windows game with no Linux support. Running it under Proton worked pretty much immediately, once the input file kerfuffle was sorted. And the game ran about as well as it did on Windows.
Next test case was EXAPUNKS, a native Linux puzzle game. That one turned out to be much harder, actually. I could start the game, but it would always crash after a couple of seconds. So it was time for me to get the debugger out. And the debugger I used was the only real debugger: strace. Unlike all the others, it does not try to misrepresent reality by claiming that C was BASIC, but rather, it only displays what syscalls the processes are making, and what the results are.
Using strace, I determined that the game was writing a crash report to /tmp. But I could not find it there. After much back and forth, it turns out that Steam does some black magic with mount namespaces and cgroups, and what EXAPUNKS saw as /tmp was actually $XDG_RUNTIME_DIRECTORY/<some longer path here>/tmp. Maybe there was also something going on with bind mounts. Anyway, there was an error message about dbus not containing the OpenURI function, so I was hoping that if I could provide that function, then the crash information would be displayed to me in firefox. That never happened!
First, OpenURI is contained in the XDG GTK portal, so I had to install the package xdg-desktop-portal-gtk. But that one by default provides OpenURI only to GNOME. I am using sway. I had to create an obscure config file to make it work, and then reboot the system. And even then, no crash report, but the error message about the non-existant OpenURI was now gone.
It turned out that EXAPUNKS was crashing and writing a crash log to /tmp/burduke-crash-log.html, then calling "xdg-open /tmp/burduke-crash-log.html". xdg-open would find the file under that name and run the OpenURI function through dbus. But dbus would escape the sandbox Steam had made, and the file name would not be translated, so by the time it reached Firefox, the file could no longer be found (because of the aforementioned mount namespace trickery), and Firefox would just decide to do - nothing. Lovely.
Once I had the file name, though, I could search for the file, and I did find it. And then I looked at it, and the reason it crashed was that the type "System.Console" could not be created.
See, EXAPUNKS was written in C#. And on Linux, it is executed under Mono, of course. And apparently someone at Mono needs to get a kick in the arse. It turns out that if the TERM variable is set to a string the system doesn't have the terminfo for, then Mono will fail creating the System.Console type, with either the exception "There was an exception creating the type "System.Console"", or sometimes the exception is even printed, and then it is a chain of things resulting finally in "Exception: Bad magic number 542." This despite the fact, that in the overwhelming majority of cases, System.Console is only used to print simple strings, and that works the same on all terminals. And because I was using Wayland, my terminal emulator was now called "foot". The terminfo for "foot" was in my local terminfo database, of course, but flatpaks run in their own environments I can't change, and I have no idea how I should do so.
So, closing Steam and restarting it setting TERM=xterm allowed me to get further. Modifying EXAPUNKS' loader script to also set TERM=xterm (because it somehow got reverted when starting the game in Steam) finally allowed the game to work. What was the message printed to the terminal, that was so important it had to crash the application? "The key could not be found in the dictionary", printed 50 times. Not saying what key or what dictionary. Apparently it was read on some kind of timer after starting the game.
There you have it. Gaming is definitely possible on Linux, even with distributions that are definitely not meant for it. Next step for me is going to be to actually start using the two hard disks I have in the system, as additional storage. I have an LVM tutorial queued up already. I'll see how it goes.