So over the course of several weeks (and several blog posts), I've created a multiplayer turn-based color-guessing game hosted on DreamHost. I've been pretty happy with it, but there's still a couple annoying quirks in the situation:
- The server is HTTP only
- Boardgame.io supports websockets, but attempting to use them fails
Both of these are related to my host: I have an old shared-hosting solution on DreamHost running Passenger Phusion, which makes it slightly trickier to support these features. It doesn't appear to e impossible: there is, for example, some discussion and a code example for setting up both SSL and websockets on DreamHost. But I think there's a simpler approach that I wanted to try first.
Friends, Heroku is unfairly good.
Setting up Swătch on Heroku
Heroku is a "Cloud Platform as a Service" (PaaS) that lets you very quickly host an app using one of several formats and frameworks, including NodeJS. Once configured, deploying changes is as easy as git push
to a relevant target.
The boardgame.io documentation includes some pretty clear directions for setting up a Heroku instance to host a game... If you already know how Heroku works. This was my first Heroku app, so I took a few more steps to get there.
For starters, I set up two new apps on Heroku (swatchgame-dev
and swatchgame
) and arranged them in a pipeline so that I can get one-click promotion of staging candidates at swatchgame-dev
to production at swatchgame
. "Every project has a development environment... Some are privileged enough to have a production environment separate from the development environment." I then installed the Heroku CLI tools on my work machine (sudo snap install --classic heroku
). That gave me the tooling to configure my git repo to work with Heroku (heroku git:remote -a swatchgame-dev
, which set up a remote that would push to my Heroku app).
To prepare my app to work on Heroku, I only needed to do a couple of things:
- In
package.json
, clean up mybuild
rule so it built both the client and the server code:"build": "npm run build-server && npm run build-client"
- Add a declaration to
package.json
to let Heroku know what Node version is expected:
"engines": { "node": "12.22.7" }
- Add a
Procfile
to the root of my project that told Heroku what to do to launch the project once it was installed. The file is a single line,web: node build/app.js
, which tells Heroku to set up handling web connections by running the app. - Make the app read from a
PORT
environment variable to check what port to bind to. Heroku sets that variable to let Node.js apps know what port to listen on for incoming connections. This required only a few tweaks to the setup logic in the server'sapp.ts
file
The necessary code change was very simple:
import 'process';
. . .
const MAYBE_PORT = Number(process.env.PORT);
const PORT = isNaN(MAYBE_PORT) ? 8000 : MAYBE_PORT;
server.run(PORT, () => {
console.log('server on');
});
Once all that was done, I simply had to push to Heroku. Heroku is watching for changes to only a couple of branches (master
or main
), so I just had to make sure my push matched the correct branch name (since I develop in a local develop
branch):
git push heroku develop:main
I then visited https://swatchgame-dev.herokuapp.com/ and... It just worked! No further changes needed. Both HTTPS access and websockets are handled via Heroku's default configurations.
Seriously, Heroku made this ridiculously easy, and it's free to use for a project this small. I couldn't recommend anything else at this juncture.
The game is now playable at https://swatchgame.herokuapp.com/... Try it out!
Look into `heroku labs:enable` too, and any language-specific enablements for runtime metrics.
ReplyDeleteCreated match, tried to join it, got:
ReplyDelete```
swatch OPEN [free], [free] Join
failed to join match sLrQIH-ytFy (Error: game instance sLrQIH-ytFy not found)
```
That'll happen from time-to-time; it appears to be a bug in boardgame.io that I haven't tracked down yet.
DeleteRefreshing the page *usually* fixes it.