I was isekaid into developing a minimal-JavaScript online game using The Platform as much as I could and wrote about it 🧙

Kat Marchán - Sep 5 - - Dev Community

(Cover image credit: Ian MacDougall, https://www.artstation.com/artwork/oOd05w)

Folks have been nudging me to write this for a while on Mastodon, so I thought I'd put together a little series on a fun app I've been working on for a bit, as I build it.

It's a web-based PWA intended for playing a family of tabletop RPGs that I'm very fond of: Ironsworn/Starforged. These games are designed around single-player gameplay with optional multiplayer rules, and gameplay ends up looking a lot like journaling plus notes. Or, you could say, a lot like a blog publishing platform. And, like blog publishing platforms, a key thing with this game is that you should be able to publish your journals for other players to read and interact with, along with your characters, your worlds, and all sorts of other creations. A community of fictional creativity, posing as a fun little game.

What's so different about this app? Well, it's meant to have a lot of the bells and whistles that you'd expect from a PWA with serious offline capabilities, but it's built unlike the vast majority of webapps these days, while still having a fully fancy/interactive UI with all the bells and whistles you might be used to seeing in them. And as of right now, it's all done with a ~40kb JavaScript payload.

Why am I doing things this way? Because I believe the web platform has come a long way, and frontend applications have gotten unnecessarily heavy, slow, and inaccessible to large portions of the web userbase by their over-reliance on legacy technology like React &co: you don't need to ship megabytes of minified JavaScript and wasm to have a really fancy, modern application. The problem? There's very little documentation about how you actually go about doing this and using the technologies available because so much of the community documentation and education focuses around JS frameworks. So... I'd like to help a bit on that front.

To give you a sampling of some topics I'll be covering:

  • The app is an entirely server-side rendered multi-page application using a plain ol' server-side MVC web framework (Phoenix, without LiveView).
  • Oh, and even the Lit web components are server-side rendered. No FOUC or loading spinners to be seen.
  • It works entirely offline, and without even having a user account. Once you've loaded the site, you're good to go to play the game on the go, and you can sync later if you want.
  • If you're online, you get access to real-time, multiplayer editing.
  • As much as possible, use the platform: HTML, CSS, and JavaScript (okay I'm cheating a bit here, because I'm using TypeScript and esbuild, but that's just nice and easy).
  • A smattering of web components used as-needed, and only to the extent actually needed, instead of using a frontend framework of any sort (goodbye, React, you're not needed anymore)
  • Because of this, as mentioned above, the JavaScript bundle is tiny, currently weighing in at ~40kb, with minimal dependencies.
  • A really fun, CouchDB-style entity synchronization system that can handle the split-brain problem and sync conflicts in a reasonable way (read: without just stomping all over older changes).
  • Using iframes (!) for things like a dynamic sidebar that you can navigate around without refreshing the current page.
  • Very, very aggressive progressive enhancement: As long as you're online, the entire application should be fully usable if JavaScript is disabled or fails (no, not just because of a handful of nerds who run Lynx), while still enhancing up to dynamic, interactive behavior.
  • Centering accessibility by using what the browser already provides as much as possible. I guess I'll also be figuring ARIA stuff that I'm not very good at.
  • Using htmx for HTML-centered in-page dynamicity (without duplicating a bunch of code!) (update: I've replaced all my usage of htmx with a tiny web component in vanilla JS instead)

I'll be getting pretty specific and technical about one application in particular during this series, rather than using isolated, minimal examples. That way, the stuff you read is essentially all "real world" code with all the complex concerns that entails. So if you're interested in reading more about any of this, like and subscribe! I'll be POSTing Through It™️.

. . . . . .