September on Linux, part 4: ReShade and first night in XIV
Before my second week on Linux was over, I could launch XIV, log in without typing a TOTP, and use most of the configuration I had brought over from Windows. But the game still didn’t look like the game I was used to playing. I wanted my ReShade presets back, as well as the overlays that had accumulated around my supposedly simple hobby of playing one video game.
I wanted to play that night. Installing the shaders seemed like a reasonable final task before doing so; finding out why installed shaders weren’t doing anything took rather longer.
🎨 Installing ReShade and GPosingway
GPosingway bundled the shaders, presets and configuration I wanted. I used version 8.2.1, with its supported ReShade 6.5.1 build with add-on support.
I used Kevin Lekiller’s reshade-linux.sh to install ReShade. The version and add-on selection were passed as environment variables:
set -x RESHADE_VERSION 6.5.1
set -x RESHADE_ADDON_SUPPORT 1
./reshade-linux.sh
In the installer, I selected installation and supplied the directory containing ffxiv_dx11.exe. That left ReShade’s 64-bit DLL available as dxgi.dll alongside the game executable. When I started XIV, the ReShade banner appeared at the top of the screen – that’s progress!
The shader compiler needed some attention, too. I copied the Microsoft d3dcompiler_47.dll supplied by the Linux installer into Wine's system32 directory. The relevant source and destination were:
cp ~/.local/share/reshade/d3dcompiler_47.dll.64 \
~/.xlcore/wineprefix/drive_c/windows/system32/d3dcompiler_47.dll
This turned out to be a detail worth remembering: a few days later, shader compilation got stuck when I tried Proton, and copying the same DLL into Proton’s separate prefix got that attempt working as well. The rest of the Proton experiment can wait for a future me.
I downloaded gposingway.zip from the GPosingway releases and extracted it into the game directory (~/.xlcore/ffxiv/game). The files I was working with were then arranged around the executable like this:
game/
├── ffxiv_dx11.exe
├── dxgi.dll
├── ReShade.ini
├── reshade-shaders/
└── reshade-presets/
Opening the overlay introduced a small problem before I could even inspect the presets: ReShade expected a Home key, which my keyboard is… somewhat lacking in presence 😬 A quick change of ~/.xlcore/ffxiv/game/ReShade.ini remapped it back to familiar Shift-F2.
[INPUT]
KeyOverlay=113,0,1,0🔎 Presets appeared, but did nothing
Once I could open the overlay, I could select presets, but they didn’t change the image at all. I suspected missing effects: the Windows ReShade installer offered optional packages like fubax-shaders and CobraFX, and the Linux installation didn’t include everything I expected. I copied reshade-shaders and reshade-presets from Windows, but the extra files still didn’t make the presets work.
The problem was in ReShade.ini: EffectSearchPaths and TextureSearchPaths told ReShade where to find the effects and textures, but the default values of Z:\home\milan\.local\share\reshade\ReShade_shaders\Merged\Shaders and Z:\home\milan\.local\share\reshade\ReShade_shaders\Merged\Textures obviously couldn’t find effects and textures supplied by GPosingway. Adjusting the configuration values like so resolved the issue:
[GENERAL]
EffectSearchPaths=Z:\home\milan\.local\share\reshade\ReShade_shaders\Merged\Shaders,Z:\home\milan\.local\share\dev.goats.xivlauncher\ffxiv\game\reshade-shaders\Shaders\**
TextureSearchPaths=Z:\home\milan\.local\share\reshade\ReShade_shaders\Merged\Textures,Z:\home\milan\.local\share\dev.goats.xivlauncher\ffxiv\game\reshade-shaders\Textures\**
I suppose I’m using ~/.xlcore and ~/.local/share/dev.goats.xivlauncher interchangeably, but they should be symlinked to one another, so hopefully it doesn’t matter 🤞
For depth-dependent effects, the reversed-depth definition belonged in ReShade’s Home → Edit global preprocessor definitions:
RESHADE_DEPTH_INPUT_IS_REVERSED=1
🍷 Juggling Wine versions
The Wine build I started with had been crashing fairly frequently; I remember it as around 10.10. I moved to managed Wine 11.4 in XIVLauncher-RB, which seemed more stable during the setup session.
There was an actual keyboard issue during the same session, though. Native applications used my custom Czech QWERTY layout, while XIV had fallen back to Czech QWERTZ. I installed the generated symbols as /usr/share/X11/xkb/symbols/custom and selected the named layout in Hyprland’s existing input table:
kb_layout = "custom",
That was the change described in Part 2, and it corrected the layout in the session I was using. The later return to XWayland exposed a separate reboot problem, which led to the setxkbmap command in the login script from Part 3. At this point, though, I could type normally, and the shaders were finally changing what I saw on screen.
🗣️ Browsingway, IINACT and cactbot
One thing I expected to be incredibly painful was getting Browsingway and TTS callouts to work – I remember reading a long time ago that Browsingway, due to embedding Chromium and essentially rendering web pages on top of the game layer, has trouble running inside Wine; text-to-speech, on the other hand, relies on Windows providing a speech synthesis service, and ideally installing some voices that don’t sound like it’s 1995.
Thankfully, I seem to have been wrong on both counts:
- Browsingway, under recent versions of Wine, works without any trouble whatsoever 🎉
- and IINACT, of all things, somehow has a hackery in its sleeve to provide text-to-speech service to Browsingway overlays 😳
The second part was probably the biggest surprise of the entire Linux experiment; I studied IINACT’s source code to confirm this, and there literally is an escape hatch that is only in effect when running under Wine (so on Linux and macOS) – it bypasses any attempts to do system calls to a speech synthesis service, and instead utilises Google’s online speech synthesis service to turn text into an MP3 file, which it then plays back to me 🤯
The only tiny problem with that approach is that Google’s rate of speech is incredibly slow, and there’s no way of telling Google to speak faster; thus my own private fork of IINACT was born – it adds a configuration option into the /iinact config window to allow configuring the playback speed; and after the MP3 file is received from Google, it runs it first through pitch-preserving time-stretching functions of the SoundTouch.Net library to speed it up (or slow down, if that’s needed for some reason) before playing it back to me. Hackery on top of hackery, lovely! 😻
📋 A Wine refill
The move to Wine 11.4 had left me with another irritation. Copying text inside XIV didn’t update the Linux clipboard; Ctrl+C was only working consistently within the game, but no content could make it out of the game or into the game.
The fix for this was remarkably simple: I just had to finally realise that Wine 11.14 is actually newer than the Wine 11.4 I was running, and upgrade from 11.4 to 11.14 🤣
By the early hours of September 13, I had Dalamud, plugins, mods, ReShade, IINACT, combat logs, overlays… and a working clipboard. This was the first night that I called playing XIV on Linux a success. The setup I wanted to bring across was finally something I could play with, and the reason to reboot back to Windows had disappeared.
🎮 Actually playing
By September 15, after about a day and a half of play on Wine 11.14, performance felt comparable to Windows, with smoother frame pacing to my eyes. The game has been remarkably stable, too.
There are still more things I want to try; for example, see how the game performs under Proton/Gamescope instead of Wine (I tried for a little bit, but going from a fully functional setup under Wine into another bunch of issues under Proton was… discouraging; I think I need a few more days and the right mood before I go deep into the land of experiments again), and check if I can get even more eye-catching HDR going.
But for the past 10 days or so, XIV on Linux has been nothing but pleasure, and I have tested it under a variety of activities, from regular daily & mentor roulettes (“only” 1935 roulettes to go 😵), crafting and gathering (even TeamCraft with packet capture and item auto-tracking works!), deep dungeons and even Ultimate raiding.
Only halfway through the month, I have completed all of the goals I have set out for myself, and I couldn’t be happier with the result! That’s not to say that this series is over – I think I have at least one more article to write, and that one will not be gaming-focused, I promise 😏