Linux Issues on Steam

I think I’ve addressed the Steam Linux issue, but, for now, I’m only rolling the fix out to one game, “Jolly Good: Cakes and Ale.” Please give it a try (you can test the demo, if you don’t own the full game) and report back.

(Before you test, you might want to right-click on the game, and go to Properties → Local Files → Verify Integrity. That will ensure that you’re running the current latest version of the game.)

For the record, here’s my understanding of the problem.

Background Terminology: Electron, Chromium, CEF

ChoiceScript games are all just web pages. On desktop, to distribute a web-page game as a native app, we distribute a private copy of Google Chrome, and configure it to only be able to open our single web page.

We use an open-source framework called “Electron” to embed Google Chrome. https://www.electronjs.org/ “Build cross-platform desktop apps with JavaScript, HTML, and CSS.”

Technically, Electron doesn’t use Google Chrome, but just the open-source parts of Google Chrome, which is called “Chromium.”

In 2014, prior to using Electron, I used another framework called the “Chromium Embedded Framework” (CEF). CEF forces me to write a bunch of code that Electron handles automatically, so Electron is better and far more popular than CEF.

Upgrading Chromium is manual effort: Whether I’m using CEF or Electron, upgrading to the latest Chromium requires manual effort, and it often breaks when I do it. As a result, I never upgrade Chromium (CEF or Electron) unless I need to, to fix a bug.

In 2017, I moved the Windows build from CEF to Electron, but I’d never switched the Linux build from CEF to Electron (because it worked fine, and upgrading would be actual work). Thus, most of our apps are currently running a Windows build with a 2017 version of Chromium, and the Linux build is running a 2014 version of Chromium.

(On macOS, we embed Safari instead of Chrome, and it’s super super easy to do by hand, so we’ve never really run into trouble with it. No special upgrades are required AFAIK.)

The Blank Screen Problem Is New

On my Ubuntu 22 Jammy Jellyfish machine, I repro the bug with a blank screen. The issue doesn’t occur on Ubuntu 20 Focal Fossa.

I’ve also reproduced the blank screen issue on Manjaro Linux, (based on Arch Linux) which is the distro that Steam recommends for testing Steam Deck compatibility. Developing for Steam Deck without a Dev-Kit (Steamworks Documentation)

We Can’t Use Proton to Fix This (But You Can)

Steam Proton is a compatibility tool to allow Linux machines to run Windows apps without recompiling them for Linux. (“Proton” and “Electron” have nothing to do with each other; it’s a total coincidence that both pieces of software are named after subatomic particles.)

As an end user, you can right-click on a game, go to the Compatibility section, and turn on Proton. There are a bunch of options to fiddle with there, and, here in this thread, @NoiramSang has explained how to turn on Proton, set those settings, and get the game to work.

Unfortunately, as a Steam app developer, I’m not allowed to automatically enable Proton or set its settings. Specifically, when I use the Steam developer console (“Steamworks”), there are a bunch of configuration options I’m allowed to set and use, but there’s no “Compatibility” section; no way to enable Proton. Individual end users like you can turn on Proton, but Steam doesn’t provide a way for us to say “Just turn on Proton for all Linux users, and use the following settings: _____.”

If we’re gonna fix this, we’re going to have to fix our Linux app “the right way,” by making an app that works fresh out of the box on Ubuntu and Manjaro.

Fixing It the “Right Way” Meant Upgrading Electron and Turning Off Sandboxing

As @NoiramSang discovered, there is an another way not to use Proton, which is to pass the --disable-disable-seccomp-filter-sandbox parameter to the Linux executable as it launches. Unlike Proton, I am able to instruct Steam to pass specific command-line arguments to my launcher; when I use it, the blank-screen issue goes away.

But even though the issue went away, I still had issues running that ancient 2014 version of Chromium on modern versions of Linux. For example, I was testing on a VM on a high-resolution “retina display” MacBook Pro, and I’d configured Ubuntu/Manjaro to increase the UI font size to match, but our Linux app wasn’t honoring those settings, so the font was teeeny tiny.

Upgrading CEF would require a ton of work on my part, and I’d hate to continue running Linux on CEF and Windows on Electron, so I decided to switch the Linux build from CEF to Electron. I’d hoped that just that would fix the blank-screen bug, but it didn’t; I still had to pass --disable-seccomp-filter-sandbox to get it to work.

While I was at it, I upgraded to the latest version of Electron on Windows and Linux. On paper, there’s no pressing need to upgrade Electron for Windows. Our Windows Steam app works fine. But it seems wise to get on the latest version of things (to delay the point at which things will randomly start breaking later on).

Initially, the new app with --disable-seccomp-filter-sandbox seemed to work fine on Ubuntu 22 and Manjaro, by which I mean: I copied a zip file containing an example ChoiceScript game to those machines, extracted the zip, and double-clicked the app, and it worked great.

But I found that there was another problem that only occured when launching the game via Steam. I submitted the app to Steam as a “beta” app, and tried launching it on Ubuntu 22. I clicked Play, and Steam just sat there, doing nothing, for almost exactly 90 seconds. (The green “Play” button changed to a blue button that said “X Stop,” but no game window opened; I couldn’t even see a blank screen.) Then, 90 seconds later, the window appeared, and the game ran.

On Manjaro, it was even worse… I think the game instantly crashed on startup. I clicked the Play button, it flashed to a blue “X Stop” button, and then instantly flashed back to a Play button, again, with no window popping up.

I had no clear idea why this was happening, but, while investigating --disable-seccomp-filter-sandbox, I found this page documenting Chromium sandboxing options. It mentioned that instead of --disable-seccomp-filter-sandbox, I could use --no-sandbox, which completely turns off sandboxing. When I used that, the app launched quickly and cleanly, scaled to the correct size, on both Ubuntu and Manjaro.

It Is Safe to Disable Sandboxing, I Think

The premise of Chromium sandboxing is that Chromium may be used to access untrusted third-party code. That code could do anything. It could try to exploit a bug in the browser, and from there, they might be able to gain access to the user’s home directory. If they’re very clever, they might even be able to exploit the kernel itself by exploiting bugs in Chromium.

But, from my perspective, we’re not running untrusted third-party code. All of the code in our game process is code that I’ve written or code that I’ve tested and vetted. We never use our Chromium browser to navigate to arbitrary web sites, so the sandbox doesn’t have much/any benefit for us.

Now, from your perspective, as a player, you might not fully trust me, and you might prefer that I leave sandboxing enabled, or at least disable it as little as possible, i.e. to prefer --disable-seccomp-filter-sandbox instead of --no-sandbox.

If the sandbox were working, if it were allowing my code to run but blocking dangerous exploits, I’d be happy to leave it on. But the sad fact is that Electron isn’t very well tested on various Linux distros. As far as I can tell, I do have to completely disable the sandbox to ensure a good experience for users, and so, that’s what I’ve done here.

6 Likes