Before you start reading, you should know that this post was written from notes I took while releasing updates for my first commercial game on Steam – which is still in early access as I write this.
If you’d prefer a video tutorial, take a look at AJ Ordaz‘s YouTube video: How to add Steam Achievements and Overlay to your Construct 3 game using Greenworks.
I use NW.js to export my game. I know there are other alternatives like Electron and Tauri. I’m not saying which one you should use. NWjs worked for me and my game so here’s how I did it.
It’s going to be a long journey for developers who’ve never done this before. There are lots of little things to learn here and there, and we’re going to go through them step by step.
It’s taken me a long time and a lot of patience, research and testing. If you notice any mistakes, errors or missing information, please feel free to leave a comment below or get in touch with me via my socials or e-mail.
Table of content
Here’s a summary of the different stages we’ll be dealing with:
- Greenworks plugin for Construct 3
- Debugging Greenworks plugin
- Construct 3 Export Settings
- Getting additional files for exports
- Preparing packages
- Uploading packages to Steam
- Testing on Steam
- Testing on Steam Deck
- Conclusion
Greenworks plugin for Construct 3
Scirra, the team behind Construct, has created an official plugin called “Greenworks” that lets you access the Steamworks API from within NW.js.
This plugin is not implemented by default in Construct. We therefore need to download the appropriate version and install it ourselves.
Let’s go to the plugin page, and download version 0.60.0 of the plugin in the “Version” tab.
I’ve tried my best to get versions higher than 0.60.0 to work, but so far I’ve never succeeded. Sometimes visual bugs when launching the game, sometimes black screens on Linux or macOS, or even random crashes on SteamDeck…
So I’ve stuck with version 0.60.0 for the time being, since it works everywhere. For me, it’s important that the game runs on as many platforms as possible.
Once you have downloaded the plugin, open Construct 3 and install it.
To install a plugin, open the Addon manager:
The “Addon manager” dialog appears. Now click on the “Install new addon…” button on the bottom left of the dialog:
Select the Greenworks plugin file we previously downloaded. It should be something like “greenworks-0.60.0-stable.c3addon”. Notice the “.c3addon” extension that Construct uses to recognize an addon file.
As soon as you upload the file, Construct will show you a warning message to warn you to install only addons from trusted sources:
We downloaded this file from Scirra’s official website and it was made by them so we should be safe enough, right?
Proceed with the installation of the plugin by clicking on the “Install” button.
Once the installation completed, make sure to restart Construct to be able to use the addon. Simply refresh the page (ctrl+R or cmd R) and if you head to the “Addon manager” dialog again, you should see the Greenworks plugin version 0.60.0 listed there.
Debugging Greenworks plugin
Now that the plugin has been installed, you can start creating the Steamworks events logic you want in your game.
When you want to debug your game’s NWjs exports, even before testing whether or not bugs come from your events, it’s vital to make sure that the Steam API has been loaded and is available.
If the API is not available, none of the Steamworks features will work. Your game will probably work fine, but not the events you’ve added with the Greenworks plugin. Such as achievements, for example.
There may be several reasons why the API isn’t available. Mostly due to not using the right versions of files together. We will go through them later in this article.
For now, lets focus on adding some events that will help us understand if the Steamworks API is available or not when we run our game on exported platforms.
The idea is to show/hide a text object by pressing a key on the keyboard. The text value of this object is :
- If Steamworks is not available, display the text “Steamworks is not available”.
- If Steamworks is available, display the text “Steamworks is available”.
Quite simple, but invaluable in determining whether the error is in our events or whether the versioning of the plugin files, NW.js and the Steam API we use are compatible or not.
Note also that for the condition to be true, i.e. for Steamworks to be available, it is imperative that the Steam client is running with a connected user in the background when you launch the game. Otherwise Steamworks will always be unavailable.
You can launch the game from the Steam client directly or from any folder on your computer (in this case the overlay might not work).
Construct 3 export settings
Now let’s assume that we’ve created all our Greenworks events the way we want them and that our game is ready for export and testing.
To export our game, click on “Menu > Project > Export” button.
A new dialog opens, asking us to choose which platforms we want to export our game to. Select the NW.js export option and click on “Next” button:
Another modal appears and asks you for export options:
I won’t go through all of them here, but you can find detailed information on the Construct 3 documentation about “Publishing projects”.
Notice I’m not asking Construct to minify my scripts. I had several bad experiences in the past where my exported games were crashing so I prefer to not minify it anymore. Plus I don’t think it really saves a lot of data. Compressing images and your audio will already help.
Hit “Next” button, then the “NW.js options” modal appears:
Here are a couple of information regarding each NW.JS export parameters:
- “NW.js version” is the NW.js version we want to export our game to. Here we selected the version 0.60.0 which uses Chromium 97;
- “Platforms” are the selected platforms we want Construct to export our game to;
- “Package assets” option means that Construct will bundle all our game project’s files in to a single compressed file named “package.nw”;
- “Compress final zip” says it all. Very handy if we want to export our game to multiple platforms;
- “Window frame” adds the default operating system window frame around our game. Players will see it only if they play in windowed mode. In full screen mode, no window frame and caption are shown;
- “Resizable window” allows players to resize the game window. This is only possible in windowed mode;
- “Ignore GPU blacklist” allows our game to run on systems with poor quality drivers. I’m not so sure about this one to be honest, but it is recommended by Scirra;
- “Export for Steam” will add a couple of Chrome arguments to our exports such as “–in-process-gpu” and “–disable-windows10-custom-titlebar”. It also forces the game window to constantly redraw to improve compatibility with the Steam Overlay;
You can find even more information about NW.js export options on the official documentation page “NW.js options dialog”.
When you are ready, click on the “Next” button to start the export.
Once the export is done, you’ll see a new dialog that will allow you to download exported files:
Download your file(s) and save it/them on your computer disk.
Getting additional files for exports
Go to the folder you saved your NW.js export in, and unzip the archive.
You should see different folders with names of platforms you wanted Construct to export your game to:
We’ll now need to add a few more files to our exports so that the game works properly on Steam. But first, let’s create/download them.
Here’s a list of what we’ll need:
- A “steam_appid” text file containing our game’s Steam ID;
- The Steamworks API SDK files for each platform;
- Greenworks prebuild files compatible with the Steam API we will be using;
Steam AppID file
You need to create an empty text file – meaning with a “.txt” extension – and add your game’s Steam ID number to it. This is how the Steam API can identify your game.
If you don’t know your Steam game ID yet, here is a simple trick.
Go to your game’s Steam Store page, copy and paste the game’s url and the game ID should be in the link path just before your game name.
Here’s an example with my game Baby Dino Adventures:
My game Steam Store page url is: https://store.steampowered.com/app/1271910/Baby_Dino_Adventures/
My game ID is: 1271910.
Once you have the id of your game, create this new text file and fill it in only with the id number of your game.
That’s all we need for our “steam_appid.txt” file. Keep it safe somewhere on your disk for now, we’ll need it later.
Steamworks API SDK files
For the Greenworks plugin events we’ve used in Construct to work, it’s imperative that we add the Steam API SDK files, otherwise nothing will work. Not even our “Steamworks is available” event we created earlier in the “Debugging Greenworks plugin” section.
The latest version of the Steam API compatible with NW.js 0.60.0 is version 1.50.
You can find a list of all SDK releases on Steamworks website at following address: https://partner.steamgames.com/downloads/list
Download the version 1.50 of the Steam SDK that has been released on Aug 29, 2020. Once downloaded, unzip the archive on your machine. We will need some of those files later.
Here is an example of where the “package.nw” file is in my Windows 64 folder of my NW.js export:
Make sure to copy and paste the sdkencryptedappticket and steam_api files to the according operating system folder otherwise it will not work.
Here is an example of how the package.nw file for Windows 64 looks once I added the appticket and steam api files:
For Linux builds, it is quite the same as Windows except that library files have an “.so” extension and that there is no need for additional “.dll” files.
For Mac builds, the exported folder structure is a bit different. You’ll find the package named “app.nw” inside the following path: “../your-game-name.app/Contents/Resources/”.
Greenworks prebuild files
This is not an easy step. It’s often the one I’ve had the most trouble with. Because it’s not easy to find out which Greenworks version is compatible with which version of NW.js and which version of the Steam API.
Fortunately, Armaldio, a member of the Construct community, has created an online tool called Greenworks Prebuild Downloader that will allow us to find the ideal prebuild files compatible with specific NW.js and Steam SDK version.
Browse to Armaldio’s website: greenworks-prebuilds.armaldio.xyz/
We’re going to use the left sidebar filters to tell the tool the exact prebuild files we need:
- Release Tag: v0.7.0 – Steamworks v1.5.0;
- OS: any you want;
- Architecture: any you want;
- Runtime: NW.js;
- Versions: v102;
Once you’ve set the right parameters, click on the download icon on the right-hand side of the screen for each operating system you want. Notice that there are different files for 32-bit and 64-bit exports too.
Once we downloaded all required prebuilds files, we can go on the next step: preparing our packages.
Preparing packages
Now that we’ve our “steam_appid.txt” file and downloaded the missing library files, we can start preparing the packages for each operating system we need:
Windows package
Go to your Windows export folder.
Copy and paste your “steam_appid.txt” file into the root of your Windows folder.
Now, we need to open the “package.nw” file. It is basically an archive file containing the HTML5 export of our game.
We’ll add two different files to that “package.nw” archive from the Steam SDK library files we downloaded previously.
First, we need to get the sdkencryptedappticket file.
We can find it in the following path: “../steamworks_sdk_150/sdk/public/steam/lib/win64/..”.
Second, we need the steam_api file.
We can find it in the following path: “../steamworks_sdk_150/sdk/redistributable_bin/win64/..“.
We copy those files and paste them into the “package.nw” archive.
Now we need to make sure that greenworks files in the “package.nw” archive are the right ones – meaning these we previously downloaded.
Notice how those files are named differently from the ones already available in our “package.nw” archive. We will need to rename them accordingly to match files name in our existing archive, likeso:
- greenworks-linux32.node
- greenworks-linux64.node
- greenworks-osx64.node
- greenworks-win32.node
- greenworks-win64.node
Once renamed, drag-and-drop these files into our “package.nw” archive file.
We are now good to go. At least for the Windows 64 build.
If we want to support Windows 32 bit computers, we will need to do the exact same steps as before but with Steam SDK files for Windows 32 bit version.
To finalize, we can create a .zip archive of our “win64” folder. We will upload this archive as our Windows build in our Steam Partners platform later.
Linux package
For the Linux package, it is exactly the same as for the Windows build.
We upload our “steam_appid.txt” file to the root of our linux folder.
Then we add Steam SDK library files and Greenworks prebuild files to the related “package.nw” archive file.
We are done with Linux builds. We can create a .zip archive of our Linux folders. We will upload this archive as our Linux build in our Steam Partners platform later.
If we want to support Linux 32 bit version, we do exactly the same steps as before but with Steam SDK libraries for Linux 32 bit. Then we include the “linux32” folder into our Linux build archive.
macOS package
For the macOS package, we will do exactly the same steps as we did for Windows and Linux. The only difference is the folder structure.
We will need to copy and paste our “steam_appid.txt” on the “Resources” folder that can be found on the following path: “../mac64/yourgamename.app/Contents/Resources/..”
Notice the “app.nw” file in the “Resources” folder. That’s the “package.nw” archive file, but with a different name for macOS.
Copy appropriate Steam SDK files (from the “osx” folder) and paste them into the “app.nw” archive.
Do the same for Greenworks prebuild files.
If you’re wondering, Apple dropped support for 32 bit versions so that’s why there is no 32 bit export of our game.
Once we’re done, we can create an archive file of our “mac64” folder. This archive will be used to upload a macOS build of our game via Steam Partners website in the next step.
Uploading packages on Steam
All our packages are now ready.
We created an archive .zip file for every operating system we want to support.
Unfortunately, I can’t share screenshots of my Steam Partners interface publicly due to the non-disclosure agreement signed with Valve.
For this reason, I will try to share as much details as possible but without screenshots and I’m going to assume that you have a minimum of knowledge as a Steam developer.
We will need to go to the “AppAdmin > SteamPipe” section of the Steamworks site to upload our packages to related depots our game may have.
Before uploading our game packages, we will have to create these depots first. These can be seen as folders where we will upload our game files. As example, for my game, I used 3 different depots that I named per platform like so:
- Windows;
- macOS;
- Linux;
You probably got it. We will upload each of our packages to the related operating system depots.
Once we created depots, we will need to define launch options so that the Steam client knows what to do when a player will click on the Play button of our game’s Steam client page.
To define launch options, we go to “App Admin > General installation”. Under “Install folder”, we set the current install folder name to our game name.
Under “Launch options”, the section below, we will create one launch option for each operating system and each architecture we want.
Let’s say we want to target all the following:
- Windows 32-bit;
- Windows 64-bit;
- Linux 32-bit;
- Linux 64-bit;
- macOS;
Then we will create 6 different launch options. One for each OS with specific rules. We will set the path of the executable, the targeted operating system, and the CPU Architecture.
Here are the configuration we are going to use for each launch option:
- Windows 32-bit
- Executable: win32/BabyDinoAdventures.exe
- Description: English
- Operating System: Windows
- CPU Architecture: 32-bit only
- Windows 64-bit
- Executable: win64/BabyDinoAdventures.exe
- Description: English
- Operating System: Windows
- CPU Architecture: 64-bit only
- Linux 32-bit:
- Executable: linux32/BabyDinoAdventures
- Description: English
- Operating System: Linux + SteamOS
- CPU Architecture: 32-bit only
- Linux 64-bit:
- Executable: linux64/BabyDinoAdventures
- Description: English
- Operating System: Linux + SteamOS
- CPU Architecture: 64-bit only
- macOS:
- Executable: mac64/BabyDinoAdventures.app
- Description: English
- Operating System: macOS
Once we are done setting launch options and the installation folder, we can go back to the “Builds” section under “SteamPipe” and upload our packages according to related depots.
Once it is done, we publish our changes and we can go the next step: testing.
Note: before sending this to production, I’d advise you to publish your new packages in a beta branch first, to make sure everything works as you’d like.
Testing on Steam
If we’ve followed the previous steps correctly, then there’s not much to test other than that the Greenworks plugin is working properly.
To do this, remember we’ve created a simple text that will tell us whether Greenworks is initialized or not in the “Debugging Greenworks plugin” step of this tutorial.
Go ahead and run your Steam application on your computer.
Log in to your Steam account if you haven’t already done so, then go to your game’s page and launch it by clicking on the big green “Play” button.
The game should start within a few seconds, as expected.
If it doesn’t, the game is either crashing or loading endlessly.
In this case, there’s probably a problem with the NW.js versions, or the library files aren’t the right ones. Go back to the previous steps, and make sure you’re using the right versions.
If it works, then press the “G” keyboard key to toggle the debug text. If the Greenworks plugin works, then you should see the text “Greenworks is available” on your screen.
Greenworks is available so this means that the Greenworks plugin is working and that all our Greenworks events should work. Make sure you test them thoroughly to make sure your events are working properly.
And don’t forget that Steam achievements can only be activated once. So if you’ve already unlocked an achievement, it won’t show up again. In this case, you could, for example, create a simple debugging text saying that the success is unlocked according to the desired action. I use this often, and it is very handy. Because you know.. It can happen even to the best of us.
Testing on Steam Deck
(coming soon)
Conclusion
It took a while to get there, right?
Well, it took me a long time to figure out how to do all this and, above all, where the problems were coming from.
If this article exists today, it’s certainly not only thanks to me. Indeed, one of Construct 3’s strengths is its community. And I’d particularly like to thank Mikal and Armaldio for their invaluable help, as well as all the other people I’ve chatted with over the years on Construct’s Discord server.
I hope this tutorial helps you. If you encounter any difficulties, have any questions or even suggestions, please don’t hesitate to leave a comment below or contact me by e-mail or via my social networks:
See you soon,
Antoine
Leave a Reply