Meteor + Electron for desktop game on steam

Hey, cutting to the chase…

End Goal: This would be building a turn based game/app that runs locally, and can be distributed on [steam](https://store.steampowered.com/).

Is it possible to run a meteor app in electron with the criteria below. Has anyone done this?

  • single player mode can run fully offline, obviously without the Online / PVP functionality.
  • Bundling all image and audio assets while still communicating with the server (galaxy) and database (mongoDb) for online PVP games?
  • PVP Needs to have the app fire server methods to update game states on the DB.
  • PVP Needs to have reactive pub-sub with the DB to update players game state.
  • Needs to have an executable that installs via steam. (I’ve not published to steam but I think that’s how it works)

Found the following packages that attempt to address this. Most seem outdated and unmaintained.
Maybe Rolling your own is not so hard… But I expect it is not straight forward.

appears these look to act exactly as a web client (getting all assets from the server / cdn)… not really what I want as this will not run offline.

and

Another one that seems abandoned

and an updated fork of it

Abandoned 8 years ago

Much appreciated.

Your best bet is the Meteor-Desktop package that is maintained by the community. It’s still very far behind (uses Electron 14) but at least you have other people using it.

Never heard about the other packages before.

Hope this helps

We have been talking internally in MCP and we would probably like to create a new meteor-desktop package with the latest versions and maybe something different than Electron (if there is a better solution) as trying to upgrade is on hold at least till we get Meteor 3 alpha with Node 18.
If anyone is interested in initiating this or helping with it, please let me know.

Not sure how many people are still using the Meteor-Desktop package but please keep in mind that we have a lot of additional ElectronJS specific code in our existing in-production apps.

While switching to another solution seems easy on paper, I would strongly advise against it. There’s nothing wrong with ElectronJS, on the contrary their update cycle and support is amazing and has only got better, not worse. It’s a proven solution with many users worldwide.

The problem is that the Meteor-Desktop package was totally neglected for years and even now we have made very small improvements since taking it into the community.

1 Like

Thanks for the feedback, I’ll keep that in mind.

Sadly no one from the original team that made meteor-desktop is still around so I’m trying to pick pieces together and most of the time I don’t have the time and in this case domain knowledge to go beyond simple updates, so any help and PRs from people working with meteor-desktop are extremely welcome.

1 Like

As I wrote before I’m happy to test any new update and also how far I can update existing packages like builder, updater etc.

However when I asked on the recent work done, I was informed it’s all about the test cases, no actual progress on the problem that we’re falling further and further behind on packages published by ElectronJS.

I know you wanted to write your own “Hello World” app to actually test it for yourself but I guess it got priotized down with all the other work you’re doing, Jan.

So I’m not sure what help you’re exactly asking for. PR’s are still open and me and others can’t use even the latest version of the Meteor-Desktop package. See Issues · Meteor-Community-Packages/meteor-desktop · GitHub and specifically this issue: Issues with 3.1.0 and Electron 14 · Issue #12 · Meteor-Community-Packages/meteor-desktop · GitHub

I don’t have any experience with maintaining a npm package so please pardon my ignorance of not understanding what exactly needs to be done. At least for someone with my level of understanding more concrete instructions are needed. We can certainly take that offline if you want me to do something and you don’t want to hijack this thread more than we already did.

Thanks!

I have in the past, but I used nw.js as I can compile the source code down to binary which was important so one couldn’t easily reverse engineer the source code. https://nwjs.io Just in case you want an alternative.

I came here to write a thread just like this, so I’m happy to find I’m not the only one doing this.

I’ve been working on a desktop build of my game this whole year and had moderately successful results with meteor-desktop integration (the game is open source).

To get it running I needed to create a fork of meteor-desktop to fix some things, one of which was merged into the original repo, another one being too hacky to submit for now. I’m also using electron-packager instead of builder since all I need are executables and not installers. These are then uploaded to Steam and I was able to get it working through their client (privately for now).

I now have big and small problems, probably due to the outdated Electron version used by meteor-desktop:

  • I wasn’t able to get a macOS build signed.
  • The macOS build at launch reports “No reference to renderer process (meteor) yet.”, but as soon as you click Restart (or Shutdown for that matter) it launches fine.
  • The Windows build shows a black screen until I alt-tab (it immediately works fine).

Some of these problems appeared halfway through development so I might have done something wrong along the way, which I could attempt to fix using the current meteor-desktop version. However, getting the app signed seems a much bigger problem as Apple often changes their requirements and I would guess updated versions of Electron deal with these issues.

Which brings me to right now as I’m planning to get a demo of my game released at the end of next week. I’m at the point where my game is ready, all I need is a bug-free Electron integration. I’ll do whatever I need to get there and I’m happy with upgrading the (fork of the) meteor-desktop package. But I wanted to ask here first, how that would even work since I’ve never made bigger contributions outside smaller pull requests.

My current plan was to:

  1. Make an iPad build to make sure the Cordova integration works fine (since I assume this is kept up to date as an official package).
  2. Either:
    a) Make a new minimal clean app with meteor-desktop just to make sure I can get the game launching without bugs. If this works, slowly add things in and see when those bugs appear. Then work up Electron versions one by one, fixing anything that comes up until I can get a signed build.
    b) Make a new minimal clean app without Meteor but latest Electron, so I learn better how Electron works. If this is fine, I can try to package the Cordova build on my own. If this also works, I can use this knowledge to try and see how meteor-desktop can be updated to use the latest Electron.

Any feedback at this point is very welcome so that we as a community can benefit and/or work on this together.

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.

3 Likes

Thanks so much! Amazing really appreciate this

Hey have you released games on steam before? Sounds like you know a few things I want to learn.
Would you be willing to share your game I’d love to check it out! Also since you have got this working I’d be curious to discuss game development in general and releasing a meteor game specifically. I’ve never done any of this before and only started coding a couple years ago, but have a game coming along nicely that I’m proud of and hope to achieve a steam release one day.

Thank you for the suggestion on nwjs.io I’m getting closer slowly to seriously start considering looking at my options. How did your release on steam go? Would you share a link?

As a stepping stone towards the Steam release, I did a soft launch right now on Itch.io, so you can see if it runs for you here: Pixel Art Academy: Learn Mode by Matej 'Retro' Jan

I should have a Steam build up by the end of the week (will also post a link then). But I don’t use any Steam integration (not even the overlay) so it won’t be anything different than the Itch release.

Otherwise, no, I haven’t released a game on Steam before, it’s my first one. But feel free to join my Discord if you want to chat anyway (the link is in the game under Extras, it’ll be a good test to see if it works for you :)).

Nice, I also have setup (sort of) an itch.io page for mine. I’ll join your discord and test out you game, let you know how it goes!

1 Like

Good news, the demo of my game got approved by Steam so it’s now available for download:

I wasn’t able to test it on Linux yet, but it seems to work on Windows and macOS just fine.

So far so good! Happy I can continue making my game with Meteor. Especially with all the Unity backlash happening these days.

8 Likes

As a bit of an update (if anyone is still following this or coming to this thread through search), here’s the current state of my integration with meteor desktop.

  • I was finally able to upgrade to the latest meteor desktop update 3.2.0 (released 6 months ago), which bumps Electron version to 17.4.11. In combination with Electron packager 17.1.2 this means the embedded Chrome version is 98 (Feb 2022, so we’re only 2.5 years behind the current browser capabilities).
  • I did however still have to do some adjustments of meteor desktop as I ran into the api.caller is not a function issue. As usual, Babel Preset is the culprit and I just added a dummy caller function to the call to babelPresetEnv.
  • For some reason, the call method on the Desktop object didn’t appear anymore so I had to re-link it in my fork.
  • Finally, what initially prevented me from upgrading electron packager (The main entry point to your app was not found.), I fixed with another dirty hack, just pointing to the asar file as the main entry point instead of the index.js inside the asar.
  • As a final QoL improvement, I skipped the minification step while packaging so the source code is readable and I have a nicer time debugging my game with playtesters (and end customers). My game is already open source, so I’m not losing anything by exposing the code this way. Even better, the CoffeeScript source maps now work as well!

You can see all these changes in the commits to my fork. I’m not sure how to fix any of these the nice way, so I’m not creating any pull requests, but I do want to thank @storyteller for getting the 3.2.0 version out for us to work from.

FYI, the app still successfully gets code signed and notarized on macOS (although I tested just for external distribution, I haven’t gotten around to trying a MAS build yet). Let’s hope this all holds up until the release in August.

5 Likes

Awesome news. Congrats! And kudos for your dogged determination to make Meteor Desktop work for you!