Back when I started working on my first game, I made it a priority to integrate Steam from the outset. Steam has always been my favorite platform, so ensuring seamless integration was incredibly important to me. While the process was fairly tedious at the time, I successfully implemented all of Steam's rich features into our little client, and it was absolutely worth the effort.
I was developing the game using Electron. Web APIs were familiar to the team and elegant enough for the game we wanted to build. The first problem I encountered was how do we even add the Steamworks SDK to our game?
Luckily for me, the folks at Greenheart Games had already developed a solution. They dubbed it "Greenworks," a native Node.js module designed to interface directly with Steam's SDK.
I had to go through a lot of trial and error to get Greenworks working in my project. At times, I ran into vague errors like "File could not be found," which I eventually discovered was referring to the Steam SDK, not Greenworks itself. Other times, the game would start and immediately crash without any warning. It was a frustrating process, but I owe a huge thanks to Armaldio for providing an incredibly helpful service to build these native modules and to Slosumo for creating a detailed guide on how to implement them properly.
So here's what we did:
I followed Slosumo's guide and had to downgrade Electron from the latest version to a build from March of 2020.
I used Armaldio's website and downloaded an Electron build of Greenworks (v85)
I downloaded the Steamworks SDK (version 1.5.0) and placed all the required files.
I were done!
However once I was done, I encountered a new issue. One of the biggest obstacles that developers encounter when using Electron or NW.js is ensuring the Steam Overlay works for their game. The Steam Overlay either won't open to begin with or will get frozen once it does open. Because the Steam Overlay is incredibly important to players, we had to find a solution.
I realized the problem might be that Chromium doesn’t update parts of the page if it detects no changes, which prevents the Steam overlay from rendering correctly. In other words, we need to force the page to refresh those areas. That’s when it hit me—the best idea I’ve ever had!
First we opened the JavaScript file that starts the window and enabled these command flags:
// This is for sure required and solved the issues!
app.commandLine.appendSwitch("in-process-gpu");
// I've included this because other people have said it has helped them, but in my case it didn't seem required.
app.commandLine.appendSwitch("disable-direct-composition");
Next, we created a canvas and added it to our Main.html file (Or you could dynamically add it on start up, but this seemed cleaner and easier in my opinion):
<canvas id="workaround"></canvas>
Then we had to ensure it covered the entire screen at all times and was always on top. Then using pointer-events
and setting it to none
we could block it from accepting any mouse input.
canvas#workaround {
position: absolute;
top: 0;
left:0;
bottom: 0;
right:0;
pointer-events: none;
z-index:9999;
width: 100%;
height: 100%;
}
Then finally we tied it all together with a simple JavaScript interval that would request a new animation frame:
var WorkaroundCanvas = document.getElementById("workaround");
function CanvasWorkaround()
{
WorkaroundCanvas.getContext('2d').clearRect(0, 0, document.body.clientWidth, document.body.clientHeight);
requestAnimationFrame(CanvasWorkaround);
}
requestAnimationFrame(CanvasWorkaround);
The result?
It may not be the most elegant solution, but it is a simple one. And I'm happy it works!