TaleSpire Dev Log 412
·Hey all!
Now that we have Apple Silicon macOS support out in Beta, it's time we complete[0] our OS collection, which is now painfully omitting Linux support. This is not just awful because I personally love Linux, but also because it's the second biggest OS on Steam[1], and yes, I am more than a little amused that Apple is losing in user numbers in the gaming sector against Linux of all things.
Data from the Steam Hardware Survey
"But wait", you might say, "I've heard TaleSpire has been working well on Linux for years now" - and you'd be right!
Valve's Wine-based[2] Proton compatibility tool has been doing absolute wonders, making Linux support essentially "free out of the box" for us. We only have a handful of lines of code that are different between Windows and Linux; everything else Proton "just" handles on its own.
But why am I writing about this now? And why don't we officially support Linux already?
Both of these questions have a straightforward answer: URL handling. TaleSpire supports custom URLs using the talespire://
scheme to have an easy way to interact with certain systems like dice, bookmarks and board imports conveniently from outside, like in a browser (like this: talespire://dice/CoolDice:2d20+3). The problem is that this never worked out of the box[3] on Linux because registering custom URL scheme handlers differs from how Windows does it. That's not surprising or bad; they are not the same operating system after all - it just means that we need to do the leg work for this ourselves since that is something Proton doesn't cover.
Now, Linux being Linux[4], there's not just one version of it. This is both a significant benefit and drawback of Linux as a whole because many distributions behave slightly differently in some ways. That said, there's also overlap and standards that most of them (especially the bigger/more popular ones) support, which leads us to our first task: Figuring out how we could go about registering our URL handler in the most standardized way possible to be as portable to as many distros as possible.
Luckily, it seems xdg-utils
are used by pretty much every distro under the sun, and they include all the MIME type and URL scheme handling goodness we need by simply creating one .desktop
file!
But before continuing with the Linux specifics, let's take a detour and look at how TaleSpire handles URLs:
- On install we tell the OS that the talespire://
exists and to please run our TaleSpireUrlRelay.exe
and pass it the incoming URL data
- The TaleSpireUrlRelay.exe
checks whether TaleSpire is running - if it is, it passes on the URL data to it; if not, it launches TaleSpire and then passes it the data
- TaleSpire receives the URL data and does whatever it needs to do with it - whether that is opening a campaign to a specific bookmark, adding some dice ready to be rolled, or something else.
The second and third steps work fine on Linux, but the first doesn't. After all, our code tells Windows how to handle our URLs, and Linux isn't Windows!
Now we have a bit of a problem. Since TaleSpire is not running natively on Linux but through the Proton compatibility layer, we can't just tell the OS to open our friendly URL Relay directly. After all, Linux doesn't know what to do with a .exe. Instead, we need Proton to start the URL Relay for us - but the way Proton works, we need to make sure we're using the correct "Proton prefix" - what that is exactly is a bit too in-depth, but the takeaway is that we need to know which Proton version Steam uses to run TaleSpire and where exactly it is stored.
We also need to match the settings of Proton, crucially "FSYNC" and "ESYNC", or lack thereof. These two are different versions of an internal feature that can drastically improve performance, which is why Proton enables FSYNC by default. But support for it has only recently been added to the Linux Kernel, so some slower updating distros[5] may still have a Kernel that only supports ESYNC, not FSYNC. Luckily, looking through Proton's source code (open source is so lovely!), it's fairly trivial to figure out how they decide when to have FSYNC or ESYNC active:
syscall(__NR_futex_waitv, NULL, 0, 0, NULL, 0);
if (errno == ENOSYS)
{
//oh no! the kernel doesn't support futex_wait and as such no FSYNC. let's use ESYNC instead
}
Regardless of the theoretical capability, users can also manually deactivate FSYNC/ESYNC, which we must deal with.
With FSYNC/ESYNC out of the way, we can check Steam's config_info
file containing the used Proton version and the path. Armed with all this knowledge, we can make a shell script that forwards the URL passed to it by the OS and starts the TaleSpireUrlRelay.exe in the correct Proton prefix and matching arguments. Having done all that, we finally have the URL Relay working and can import boards from the internet with a single click!
However, we aren't quite done yet. We still need to add this to our first run install script, so the aforementioned shell script is still set up manually, and there are still a few open questions we need to figure out. But! The bulk of the work for supporting the talespire://
URLs is done. Once we wrap this up, we should be feature complete out of the box on Linux - but it still doesn't quite say we "fully officially support Linux" unfortunately. As we understand it, we can't tell Steam that using Proton is the approved way to play TaleSpire on Linux, meaning Linux support won't show up on the store page, and we do still need to figure out how we intend to support bugs encountered with Proton properly. While Proton is insanely good, whenever it does fail, we have almost no way to change anything about it, so fixing Proton-specific bugs can become quite a nightmare[6].
Disclaimer: This DevLog is from the perspective of one developer. So it doesn’t reflect everything going on with the team
[0]: It's technically not truly "complete", since we do not support Intel Macs, but I'm giving us that point since that is still macOS, just with different hardware.
[1]: Yes, I know it's also the second smallest. Yes, I am absolutely phrasing this very carefully to make Linux look as good as possible. No, I will not stop doing that.
[2]: Proton is an open-source extension/wrapper/fork/... to https://www.winehq.org/ developed and maintained by Valve (and others). It is heavily based on the core Wine project but adds extra (game-specific) fixes, tools and quality-of-life improvements for a better "out-of-box experience". Most of what I'm talking about here applies to Proton and Wine equally.
[3]: Though there has been a tool created by the community to set it up fairly quickly and easily: https://github.com/LividJava/talespire-linux-uri
[4]: What you're referring to as Linux, is in fact, GNU/Linux, or as I've recen-...
[5]: From the big distros, this includes the latest Ubuntu LTS (22.04) and all distros based on it
[6]: We've only ever had two issues we could narrow down to be only on Linux/Proton: video codecs not working (which has since been resolved by a Proton update) and a bug with Symbiotes we fixed before shipping it. Every other bug reported by a Linux user was an error in our code affecting all platforms.
Guest
UserGuest
User