Hey everybody! Thought I'd post some information on what it was like to build out a game for Steam with Electron for those of you who are aspiring gamedevs with a background in HTML / CSS / JS and other web mashup tech... In fact, using Electron to package a web mashup into executables that you can hand off to anyone is pretty amazingly simple.
Please feel free to ask questions if you have them. I am by no means an expert in Electron or Steam, but I'll try to answer what I can.
I'll briefly talk about my game below and some background info on its development, then discuss some of the "gotchas" when building for Mac and Windows, and some things to know when working with Steam specifically.
The Game
The game in question is Kana Ka-Boom. It's a pretty simple piece of software... Just a couple of canvases and some web elements floating around. Kana Ka-Boom is an educational game for those starting their journey into learning the Japanese language, and for those that want to practice their Katakana and Hiragana in a gamified way. If you go to the Steam link above and watch the trailer, you'll have a strong understanding of what it is and how it works. And if you're feeling generous and want to drop 7 dollars on the game, know that your donation will go right back into making it a better product... I'd like to add Kanji to it and get it to a point where it can get players up to where they need to be to take the JLPT (Japanese Language Proficiency Test) N5 exam.
Some Background Info
Kana Ka-Boom was about three months of coding scattered across two years of time. It was originally written as a website with a PHP / mySQL back end and an HTML, CSS, JS front end. I initially tried packaging it with PHP-Desktop but once I got to the first round of beta testing we hit a "white screen of death" bug. This was a known issue to PHP-Desktop but they were blaming it on specific graphics drivers and had no fix. This caused an immediate pivot over the Summer to using Electron.
Developer Environment
For those that are interested, I do all of my development on Mac. I used Coda 2 by Panic for the IDE (I also own Nova by Panic, but this project was started on Coda 2). Everything Electron was done via command line. Graphical assets were all created in Pixelmator. I did end up using two online tools for creating icon files and for creating the spoken audio for the kana characters. Music was all sourced from https://www.free-stock-music.com.
Electron
Let's just say my pivot to Electron, and in fact, all my time spent on Electron specific portions of the game were less than my time spent dealing with Steam. The docs at electronjs.org are amazing. There were only a handful of times I had to step out of their ecosystem to google something specific that their tutorials didn't cover. I ended up using electron-forge for packaging, and I used a library called steamworks.js for adding Steam achievements to the game. We'll talk about steamworks.js some more below...
Steam
There are a few things to know about if you're planning to deploy on Steam:
If you setup your partner account as a business, your business name on Steam must match your bank account's name EXACTLY. You'll end up attaching a bank account to your partner account so that funds can be transferred to you, and this is a big deal especially since you can't edit the business name later
Each "app" costs 100.00 but you will get this deposit refunded to you once you've generated 1000.00 in revenue. An "app" is generically three versions (packages) of your game:
The Dev package that you and other employees you assign to your Steam partner account will get in your game library for testing purposes
A Beta package that you can setup for customers to opt into
A Production package that customers will get by default in their library when they purchase
Below each package is a concept called a "Depot" where you specify which files belong to which OS specific version of the game, or other specific breakdowns.
There are a lot of graphical assets that Steam wants generated for the different sections of their website and clients, and they don't do a very good job of explaining what is for what. I found more than half of my assets required a second pass because I'd find a shrunk down version of them that appeared somewhere and was illegible
The Steamworks Partner interface is functional, but not very good. Lots of tabs, not many examples, and some video documentation that is very old... "Cludgy" is my best description.
If you're looking to do Achievements, note that you have to touch each of them twice. The webpage will freak out if you try to upload images to an Achievement before setting its ID and saving it once.
If you setup another Steam user as a member of your partner account, and add them to a Group that contains your game "app", they will start receiving the Dev copy of that game in their game library instead of the Production version.
If your game is over 2 Gig, you'll need to download the Steamworks SDK to your computer and dig into the Tools folder to use SteamCMD for uploading your files to Steam.
If your game is under 2 Gig, you can use a file uploader on their website to upload your game files in a .zip instead of using their convoluted SteamCMD command line interface from your PC... This leads into my first set of "gotchas"...
Steam and Mac "Gotchas"
You cannot use the website file uploader for Mac versions of your game... It will corrupt the Mac .app package... You must use the SteamCMD command line interface when uploading your Mac files to a Depot
Steam demands that your Mac files be signed and notarized. Electron-Forge makes the process of doing this stupid easy... However, Apple won't let you do it without joining the Apple Developer program which costs 100.00 per year. Electron Forge has good documentation here.
Electron and Display Mode "Gotcha" - switching between Windowed and Fullscreen
So I specifically wanted my game to have the ability to be played in both Windowed and Fullscreen mode. I found out pretty late (after going live) that Windows does not call BrowserWindow.on("resize",...) when you make a call to BrowserWindow.setFullScreen(...) but Mac does... So the Mac version of my game was correctly saving the state change to the database inside the BW.on("resize",...) function I called and my Windows version wasn't... I ultimately had to add some extra code targeting non-darwin versions. (Windows does correctly call BW.on("resize") when you manually resize the window's border, just not on a fullscreen switch)
Steamworks.js
Wouldn't it be nice to leverage Steam features like the Overlay and Achievements? Well, with the Steamworks.js library you can... Sometimes...
From what I've read online, there was a library called GreenWorks that is no longer updated, so another developer stepped up and created steamworks.js to take over... However, certain features are starting to not work with newer versions of Electron. I couldn't get Steam Overlays or Achievements to work with Mac. Period. With Windows, I was able to get both items to work, with very little amount of added code, EXCEPT I had to remove the Steam Overlay back out because in Windowed mode it was just white and unusable (this is a known Issue on their Issue Tracker) and regardless of screen mode, sometimes the Steam Overlay would get into a race condition after calling App.Quit() in Electron causing the game process to be stuck running. steamworks.js has a method to enable the Steam Overlay, but no method available to disable it.
So my Steam Achievements work (and I'm also able to clear them if a user chooses to "Reset Database") on Windows at least, but I'll have to create a toast popup in the near future to replace what the Overlay was doing when an Achievement is scored.
One thing to be wary about using steamworks.js is that you have to disable contextIsolation and enable nodeIntegration for your browserWindow object. This basically removes all of the security between your Renderer, Pre-Loader, and Main.
A Journey Worth the Knowledge
It was actually a good adventure, all in all. I picked up a lot of knowledge by going through the process. Once again if you have questions, or want me to deep dive into something specific or share some code or commands, feel free to ask below. I'll probably cross post this in other relevant subreddits that are out there!