I managed to get a working build for Steam, Windows + macOS + Linux. It turns out I didn’t have to upgrade anything at all, I just had to wrestle with some plugins and signing.
Here are all the things I did, before I forget any details, in case anyone comes across searching for this info in the future.
- I used a custom fork of meteor-desktop 3.1.0 which fixes a small issue with babel version not being sent to presetEnv in the app and bundler. I had to use
export METEOR_PACKAGE_DIRS="/<YOUR PATH HERE>/meteor-desktop/plugins"
when running for the plugin code to be pulled from the local packages with this fix.
- I used electron-packager 14.0.4. When running the packager, it recommends version 15.4.0, but I was getting the error
The main entry point to your app was not found. Make sure "…/.meteor/desktop-build/app.asar/index.js" exists and does not get ignored by your ignore option
which doesn’t occur on 14, so I’m sticking to that for now.
- When packaging, I set the server to localhost to have a completely offline build. So far it works fine, the sock just silently fails in the console. The URL could be set to my actual server to have a build that also communicates with the server for multiplayer.
- The desktop skeleton app comes with a meteor-desktop-splash-screen plugin. I removed it since I was getting some weird launch behaviors. Additionally, the macOS build crashes at first and displays the shutdown/restart dialog box. I couldn’t get around this so I simply removed the handler provided by the skeleton app and let it crash silently, because the game then runs normally. I’m not happy about this, but at least it works.
- I sign the app through the packager, but notarize it manually (I needed more control over all the issues that arose). After packaging, I have to notarize the app right away without running it. When you run the app, the .reify-cache files change inside the app itself so the signature becomes invalid. But if you notarize it first (and staple), the app will pass notarization and launch fine. To test afterwards, I copy the app to desktop and run it from there to not mess up the packaged version. I then use Steam’s CLI to upload the build.
- I had to add
--strict
and --deep
arguments to the signing process. I couldn’t find a way to send this in through the settings, so I manually edited electron-packager/node_modules/electron-osx-sign/sign.js to add thouse to the args
variable on line 146. Hopefully, new versions will fix this, otherwise I’ll have to make a fork for this as well.
For reference, here are the important parts of my desktop settings.json file:
{
...
"plugins": {},
"devDependencies": {
"electron": "11.5.0"
},
"packageJsonFields": {
"author": "...",
"private": true,
"devDependencies": {
"electron": "11.5.0"
}
},
"packagerOptions": {
...
"electronVersion": "11.5.0",
"platform": "darwin, win32, linux",
"osxSign": {
"hardenedRuntime": true,
"entitlements": ".desktop/entitlements.plist"
}
}
}
The entitlements.plist required for Steam:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.cs.disable-library-validation</key>
<true/>
<key>com.apple.security.cs.allow-dyld-environment-variables</key>
<true/>
</dict>
</plist>
Here’s my package script set to localhost (and displays output of what is going on):
export DEBUG=electron-packager,electron-osx-sign
meteor npm run desktop -- package 127.0.0.1
To notarize, I use this script (you can call it with zip
, submit
, staple
, assess
, or all
to perform all 4 steps, and log
followed by the ID to download the log if submit reports an error):
if [ ${1-''} == 'zip' -o ${1-''} == 'all' ]
then
ditto -c -k --keepParent .desktop-package/<path to your darwin app>.app/ .desktop-package/<path where you want the zip>.zip
fi
if [ ${1-''} == 'submit' -o ${1-''} == 'all' ]
then
xcrun notarytool submit --wait --apple-id <your id> --team-id <team id> --password <pass> .desktop-package/<path where you want the zip>
fi
if [ ${1-''} == 'staple' -o ${1-''} == 'all' ]
then
xcrun stapler staple .desktop-package/<path to your darwin app>.app
fi
if [ ${1-''} == 'assess' -o ${1-''} == 'all' ]
then
spctl -vvv --assess --type exec .desktop-package/<path to your darwin app>.app/
fi
if [ ${1-''} == 'log' ]
then
xcrun notarytool log ${2-''} --apple-id <your id> --team-id <team id> --password <pass> notarize-log.json
fi
And my main package.json with all electron dev dependencies and links to custom meteor-desktop:
{
...
"devDependencies": {
...
"@meteor-community/meteor-desktop": "../meteor-desktop",
"electron": "11.5.0",
"app-builder-lib": "23.3.1",
"electron-builder": "23.3.1",
"electron-packager": "14.0.4"
},
"scripts": {
"desktop": "node ../meteor-desktop/dist/bin/cli.js"
},
...
}
Hopefully this helps someone in the future. I’ll post the link to my game’s demo when I make it public for people to see if it runs for them.