Bigi Lui
2020-04-22 ⋅ 12 min read

Big 2 Card Game, Svelte, JAM Stack

I've been working on a web-based multiplayer card game. Think Poker, but a different game. It's called Big 2 in Asia, or Deuces in America.

I started partly because of the current stay-at-home order and folks want games to play; partly because as a parent, and as my friends and I grow older, we don't have time to sit at a computer at a set time to play synchronous online games together anymore; partly because after many years away from game dev, as someone who is a gamer at heart, I itch a little bit about developing games side project for fun.

Developing this project has really been a proof-of-concept for myself on a few things.

Using the Svelte framework to build a full app's frontend from start to finish, to learn about all its quirks and how the development flow feels.

Although I started my career as a frontend developer more than a decade ago, over the years I've grown to enjoy backend and architecture more. Most recently, prior to my current job, I was still doing full stack development (albeit as a lead and less hands-on coding time than others), and worked on a React codebase for a year. In my last post I expressed my dislike of a React codebase. I do favor a component-based frontend though, so I wanted to give other frameworks a try.

I first started venturing into Vue a little bit, and stumbled upon Svelte and quickly started playing around in it. It's a very appealing frontend framework to work with, and I've been looking forward to a chance to develop a full app based on it.

Reading Hello World examples and even tutorials of building full fledged apps can be deceiving in how daily life actually feels working with a framework. I wanted to try my hands at getting through a full app and learning all the quirks of a framework.

Creating a web app with a JAM stack frontend (statically-generated).

I learned about the JAM stack around the same time as I learned about Svelte. It's a fascinating new trend of web app development. I'm personally not a fan of the standard models of a React app where you either server-side-render the page the user landed on (e.g. Next.js), load the JS bundle and "hydrate" the app, or simply load an empty HTML page with the full JS bundle and let the page render. I think both models are flawed -- rendering a React-built frontend into HTML is resource-intensive and you're doing it either on server side or client side, on every site load.

The JAM stack is all about static site generation. You pre-render all the HTML output of the site, whether you built it with Svelte, Vue, or even React. Visitors hitting the site load some HTML files much like they used to load web sites from the 90s. In my opinion, that's how web sites are meant to be loaded, even if you're building a SPA (Single Page App) and even if you still do have JS bundles (hopefully lighter weight ones in the case of Svelte and JAM stack; with proper dynamic imports/code splitting).

The A (API) part of the JAM stack is much more similar to your typical React codebase. You talk to an API endpoint, and get JSON responses back. In the case of Svelte, there's a lot less boilerplates needed like what you might have to do with Redux. I plan to take a deeper dive in this topic in the next article about this project.

Building a hobby web app with frontend hosted on Netlify, backend hosted on Heroku free tier (bonus: making use of Heroku Redis and Heroku PostgreSQL as part of its free plan) -- the entirely free stack on modern tech.

I learned of Netlify a while ago, but only briefly played around with it for a test, never actually put a project live on it. From what I've seen so far, Netlify is great. The deploy process is so easy and smooth, and deployed sites are really fast. Netlify does have support of dynamic functionality like Serverless Functions (which is really similar to AWS Lambdas), but their core business is in serving a static site -- which plays perfectly with JAM stack sites since that's what it is. (In fact, Netlify is a big proponent of JAM stack and is the organizer of the JAM Stack Conf)

Heroku on the other hand is great for hosting an app backend. A lot of mobile apps have their backends hosted on Heroku. You can host a web site on Heroku too, but a lot of their products are geared toward backend development, like also providing a PostgreSQL database and Redis server. A combination of Netlify and Heroku will allow you to take a personal hobby project pretty far without paying a cent. (at least, as of their price plans in April 2020.) And the best of all, in the small chance that you build a personal project that ends up taking off in traffic, it would be a lot easier to scale it up. (It certainly won't be effortless, but will be a lot easier than if you were managing your own servers in AWS or Digital Ocean, etc.)

Building a web server + websocket upgrades in one server codebase (in node), also utilizing Heroku's support for this.

I wrote a simple websocket server in node.js for a past personal project, a Karaoke web + mobile app which I've written about in the past.

It was much smaller of a project without scale in mind and there was no plans to expand it beyond the one server that powers it.

I wanted to build a proof-of-concept websocket game server that supports synchronous games (as well as asynchronously taking turns) with node.js and websockets; with the ability to scale to multiple servers when needed. I know among thousands of web games studios out there, this has been done hundreds of times, but I haven't done it personally and am interested in designing such an architecture. This is another topic I'd like to do a deep dive in in a future article about this project.

An experiment to organize the frontend and backend (node.js) codebase of an app in one monorepo, but without the use of anything like Lerna, simply by organizing them in logical folder structures and having frontend build toolchain (rollup in this case) configured to work with this.

Call me having been burned by a big monorepo containing an isomorphic React codebase that uses Lerna. I'm just not a fan of it. The Lerna build step with hoisting is slow and unreliable. It was difficult to know when do you have to rebuild/rehoist while in development, when using Lerna. And then there's small pet peeves of mine like having a packages folder in root along with package.json which really messes with my use of the tab key in the terminal to autocomplete filenames.

Because my current role at my company now is a backend engineer and architect, this would actually be my first project where I, 1) work on full stack, 2) on a full JS (frontend and backend) codebase, ever since I left my last company. And this time I'm determined to structure a codebase where I can have backend and frontend share certain code/libraries, but not use anything like Lerna.

I believe all it takes is to structure and divide your backend and frontend code, keep shared libraries in a sensical place, and set up your rollup config file to look in the correct path. And that is what I did! This is again a topic I'll dive deeper into in a future post. It's possible that this was even only feasible because I went for a JAM stack frontend; and with a React isomorphic codebase it may simply be too hard.

Next time, I hope to have a finished product to show, and do a deeper dive into some of the technical topics above; show some code, and talk about architecture. With a full time job and a toddler, I can't promise I'll finish the project any time soon, but at least I'm pretty enthusiastic about it and making small progress regularly!