How to export your Construct 3 game for Steam (and Steam Deck)

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

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:

Click on Menu > View > 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:

Screenshot of Construct 3 export options showing the NW.JS option selected

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:

NW.js options are saved automatically by Construct 3 in your browser cache. Next time you’ll do an export, Construct will prefill all these export options again for you.

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:

If you want to use a custom app icon for your game, double click the “WindowsIconUpdater.exe” file to run the application and update the app icon for your Windows builds.

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:

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.

A steam_appid.txt text file containing our Steam game id.

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

To access this page you will need to login using your Steam Partner account.

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:

The “package.nw” file is an archive containing all our game files.
It basically contains the HTML5 export of our game if you prefer.

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:

Notice that Windows requires additional .dll files for any .lib files.
Make sure to add them accordingly.

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/”.

Mac export folder structure is a bit different compared to Windows and Linux exports.

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;
It’s important to select the ABI version that includes the version of NW.js we used, i.e. 0.60.0. Look at the “Version range” column which states “from 0.59.0 to 0.64.0”.

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.

See “steam_appid” text file is selected and inside our “win64” folder for Windows 64 bit.

Now, we need to open the “package.nw” file. It is basically an archive file containing the HTML5 export of our game.

See “package” file is selected. It is an archive file, but with .NW extension.

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.

Notice that Windows requires additional .dll files for any .lib files.
Make sure to add them accordingly.

Now we need to make sure that greenworks files in the “package.nw” archive are the right ones – meaning these we previously downloaded.

One greenworks prebuild file for each operating system and its 32 bit or 64 bit version downloaded from Armaldio’s online tool: Greenworks Prebuild Downloader.

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.

Since I want to support Windows 32 bit version, I archived both folders (“win64” and “win32” folders) into one archive that I will use as my Windows build on Steam Partners website.

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.

The Linux 64 bit folder of our NW.js export with its “steam_appid.txt” file.

Then we add Steam SDK library files and Greenworks prebuild files to the related “package.nw” archive file.

The Linux 64 bit package.nw archive with updated greenworks prebuild files and Steam SDK’s library files for Linux 64 bit.

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.

Our Linux build containing both Linux 32 bit and Linux 64 bit versions.

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/..”

macOS builds have a different file structure than Windows and Linux builds. We need to add our files in the “Resources” folder.

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.

Our macOS build archive containing updated greenworks prebuild and Steam SDK library 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.

See highlighted files. These are our OS-related archives. One for Linux, one for macOS, and one for Windows.

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.

An example of how I show the text “Greenworks is available” in my game “Baby Dino Adventures”. Debug text is visible on the top left of the 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


Posted

in

by

Comments

8 responses to “How to export your Construct 3 game for Steam (and Steam Deck)”

  1. Zizaco Avatar

    Thank you for this very detailed article! Dealing with all the compatibility between versions would be a huge burden without your help.

  2. mike Avatar

    What about steam deck? Is linux version is for steam deck? What other requirements are for steam deck?

    Thank you for your help

    1. Antoine G. (Author) Avatar

      SteamDeck runs on Linux so if you provide a Linux build, Linux users, SteamOS users and SteamDeck users should be able to run your games.
      If you don’t provide a Linux build, SteamDeck can still run a Windows build of your game using Proton. Proton is a third party library provided by Valve to run Windows build on Linux environment. It is effortless for devs and players but it means Steam will emulate a Windows build on a Linux environment.
      Whatever the option you choose, the most important to have for your games to be playable on SteamDeck right now is the ability for your game to be playable via a gamepad. Having full gamepad support is even better if possible.
      This way all this should be effortless for you and players thanks to the amazing work of Valve with SteamOS and Proton.

  3. Julianinho Avatar
    Julianinho

    Hello,
    Thank you for your tutorial 😉
    I have try it, but I have a problem, when I launch my game .exe, i have this at startup and it’s stuck on this screen: https://i.imgur.com/kewKDjc.png

    The game .exe was working fine before I modified package.nw.
    It can be a problem with the version of steam api file or something that?
    Thank you

    1. Julianinho Avatar
      Julianinho

      If it can hel other, I have find the solution, you need to use WinRar instead of 7zip to copy/paste the file into the file “package.nw”
      7zip don’t work well to drag file into the “package.nw” without unzip.

      1. Antoine G. (Author) Avatar

        Sorry for the late reply.

        I don’t use 7zip so I don’t know about it. I use WinRar so I can confirm it works with WinRar, indeed.

        Thank for passing by, taking the time to respond and share an update with the solution.

        I hope this can help other fellow Construct devs too.

        Cheers,
        A

        1. Julianinho Avatar
          Julianinho

          No problem and thank you for your message 😉
          Great days!

  4. Michels Avatar
    Michels

    And the save files, where are they located to point to the cloud?

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.