I've been getting back into PC gaming for the last couple of months, and that has involved a lot of checking out what Steam on Linux looks like nowadays (i.e. playing lots of games). Most of the time everything works just fine and smoothly, but sometimes there are hiccups and yesterday I was motivated to learn how to debug them. Our story begins: *Mark of the Ninja* wouldn't start when clicking on the "Play" button from within the Steam client.
For context I'm running Steam on Fedora 19, 64 bits. I have a separate "Library" folder on another partition on which I install the games instead of Steam's default location in ~/.local/share.
Running the game from the command-line
Launching from the Steam client gives me zero information, just a brief black screen, so I thought I would see what happens when attempting to launch the game from the command-line.
jpichon@localhost:~/games/steam/SteamApps/common/mark_of_the_ninja/bin$ ./ninja.sh dlopen failed trying to load: /home/jpichon/.local/share/Steam/ubuntu12_32/steamclient.sowith error: libtier0_s.so: cannot open shared object file: No such file or directory [S_API FAIL] SteamAPI_Init() failed; Sys_LoadModule failed to load: /home/jpichon/.local/share/Steam/ubuntu12_32/steamclient.so [S_API FAIL] SteamAPI_Init() failed; unable to locate a running instance of Steam, or a local steamclient.dll. ./ninja.sh: line 3: 6477 Segmentation fault (core dumped) ./ninja-bin32
Note that the Steam client must be started in order to even get that far. That library does exist at that location, let's see what's preventing it from being loaded:
$ ldd /home/jpichon/.local/share/Steam/ubuntu12_32/steamclient.so linux-gate.so.1 => (0xf77cb000) libtier0_s.so => not found libvstdlib_s.so => not found librt.so.1 => /lib/librt.so.1 (0xf67f4000) libX11.so.6 => /lib/libX11.so.6 (0xf66ba000) libusb-1.0.so.0 => /lib/libusb-1.0.so.0 (0xf66a1000) libopenal.so.1 => /lib/libopenal.so.1 (0xf664a000) libpulse.so.0 => /lib/libpulse.so.0 (0xf65fa000) libgobject-2.0.so.0 => /lib/libgobject-2.0.so.0 (0xf65aa000) libglib-2.0.so.0 => /lib/libglib-2.0.so.0 (0xf647b000) libdbus-glib-1.so.2 => not found libnm-glib.so.4 => not found libnm-util.so.2 => not found libudev.so.0 => not found libm.so.6 => /lib/libm.so.6 (0xf6437000) libdl.so.2 => /lib/libdl.so.2 (0xf6432000) ...
A number of these libraries already exist in Steam's ubuntu12_32 directory. Let's add it to our library path.
$ export LD_LIBRARY_PATH=/home/jpichon/.local/share/Steam/ubuntu12_32:/home/jpichon/.local/share/Steam/linux32 jpichon@localhost:~/games/steam/SteamApps/common/mark_of_the_ninja/bin$ ldd /home/jpichon/.local/share/Steam/ubuntu12_32/steamclient.so linux-gate.so.1 => (0xf7749000) libtier0_s.so => /home/jpichon/.local/share/Steam/ubuntu12_32/libtier0_s.so (0xf676b000) libvstdlib_s.so => /home/jpichon/.local/share/Steam/ubuntu12_32/libvstdlib_s.so (0xf6727000) ... libdbus-glib-1.so.2 => not found libnm-glib.so.4 => not found libnm-util.so.2 => not found libudev.so.0 => not found
Yup, that does seem to help. Let's add the rest:
$ export LD_LIBRARY_PATH=/home/jpichon/.local/share/Steam/ubuntu12_32:/home/jpichon/.local/share/Steam/linux32: /home/jpichon/.local/share/Steam/ubuntu12_32/steam-runtime/i386/usr/lib:/home/jpichon/.local/share/Steam/ubuntu12_32/steam-runtime/i386/usr/lib/i386-linux-gnu: /home/jpichon/.local/share/Steam/ubuntu12_32/steam-runtime/i386/lib/i386-linux-gnu $ ldd /home/jpichon/.local/share/Steam/ubuntu12_32/steamclient.so | grep not $
Excellent! Let's see if the game can run from the CLI now:
$ ./ninja-bin32 [S_API FAIL] SteamAPI_Init() failed; no appID found. Either launch the game from Steam, or put the file steam_appid.txt containing the correct appID in your game folder. Segmentation fault (core dumped)
How to find a Steam appID?
That one's easy to find a solution for. One can either look at the ID in the store URL as linked earlier or check out steamdb. Let's create a file with the correct ID in that directory and try again.
$ emacs -nw steam_appid.txt jpichon@localhost:~/games/steam/SteamApps/common/mark_of_the_ninja/bin$ ./ninja-bin32 Setting breakpad minidump AppID = 214560 Steam_SetMinidumpSteamID: Caching Steam ID: 76561198074768941 [API loaded no] ERROR: Missing required OpenGL extensions. ERROR: Missing required OpenGL extensions. ERROR: Missing required OpenGL extensions. ERROR: Missing required OpenGL extensions.
Missing required OpenGL extensions
At first I thought that was it - my laptop simply wasn't powerful enough to play the game. But fear not, ArchLinux came to the rescue and thanks to them I learnt about the handy -enablelog flag for the game.
$ ./ninja-bin32 -enablelog ... $ less ~/.klei/ninja/log/rendering.log ... [16:34.09] (4144580416) EXT_texture_compression_s3tc required
The solution is to install the libtxc_dxtn package (available in rpmfusion-free) and/or set force_s3tc_enable=true as an environment variable (discovered in a cached version of the developer's official forum, as it's currently showing blank pages for me).
I think I had to restart X to make sure the new library was picked up correctly, and then success!
Additional notes: The game still requires the Steam client to be running, and the Steam overlay won't work. However your Steam status will be correctly shown as in-game and the time, etc, should update correctly.
Starting the game from Steam
Unfortunately, starting the game from Steam still didn't work, and I also happen to quite like the overlay especially for games that don't react well to Alt-tabbing. I modified the ninja.sh script to add the new paths and environment variables, with no luck.
To help with troubleshooting: right-click on the game name then go to Properties, there is a "Set launch options" button. There we can add the friendly -enablelog flag discovered earlier. Trying and failing to launch the game again gives us some helpful logs in the same location as before in ~/.klei.
crash.log: [17:25.42] (4144023360) Failed to CreateDevice [17:25.42] (4144023360) KGraphics failed to initialize. rendering.log: [17:25.42] (4144023360) EXT_texture_compression_s3tc required
Sadly, the same problem as before - it turns out ninja.sh is likely not used at all when launching from Steam so the extra environment variables are not being picked up.
If Steam isn't using ninja.sh, how can I find out what it is using and if I can change it?
In the end, installing libtxc_dxtn.i686 (in parallel to the .x86_64 version) resolved the problem. I'm not sure why the game insists on using 32 bits libraries when articles over the web make it clear it supports 64 bits, but either way that did the trick and the game now behaves correctly like any other Steam game.
I'm still somewhat unhappy about that last part because it was more guesswork than debugging, and I don't feel equipped to properly gather information next time a similar issue occurs. How can I know which binary / path / file Steam is trying to launch and with what flags?
Hopefully while I go on to continue my Steam journey, this will have been helpful to someone else. Happy gaming!
Bonus track: the game is sloooow
After all this, it turns out my laptop is indeed a bit underpowered to play this particular game. Deactivating blur, bloom and displacement in the options helped, and so did greatly lowering the resolution (windowed mode would help too but it became pretty much unreadable to me then, so I favoured the fullscreen 640x480 instead. Your tolerance levels may vary!)