TL;DR It’s Texas Hold’em Poker. Build with Node.js, Next.js and Redis. You can check it out here nightlypoker.co.
Last year some friends and I wanted to play some poker online. After a bit of research, we didn’t find anything that we liked. We either had to download something, register, couldn’t play together or had to go through a pretty unintuitive and ugly design. So I decided to build it myself.
I started somewhen in July 2017 and with this post, I want to give some insights on my journey. It’s my largest side project so far and I’m very excited to share it with you.
Understanding the Rules
Before anything else, I had to understand the rules of poker, even though I play now and then there was still a lot I didn’t know about so I gathered all the information I could get and came back to it later when I implemented the specific rules. In this phase, I also planned how the game loop is supposed to work and what player events can occur. Of course, I couldn’t think of everything and I had to extend/rethink it during execution.
Here I was sort of biased on what technologies I want to use. For the frontend I went with Next.js since I like React and already had experience with it. For the backend, I chose Node.js and socket.io. As database I came to love Redis since its in memory saving is fast and has a build in pub-sub system which came in handy.
The database is hosted on DigitalOcean and uses Stunnel to connect to the backends(s) over TLS, which are hosted on now.
This is the final result. Before I came to that I had some other approaches with a lot more features in mind. For example, users should be able to register by only using their email (similar to Medium or ZEIT) and keep track of games they played. Firebase seemed to be suited for handling users and bringing all the live updates from the games to the players.
But as I went on I had to drop some features to save time, money and making the game itself more secure. The login process was already finished and worked but realizing that most users will just be anonymous players and later that the Firebase database wasn’t so fitting as well, getting rid of it was the best option.
But why wasn’t Firebase fitting? Well, I had to remove Firebase from the client and only allow the backend to access it (so every player would just see their cards and stuff like this). I don’t think Firebase should be used like this. So I switched to Redis and implemented the live updates myself. And since I use DigitalOcean I can decide where my database will be hosted and got rid of some latency issues as well.
This one went hand in hand with the technologies I used. The frontend is just what the users see and how the data from the backend will be displayed. The backend instance(s) are responsible for all player actions and do the processing. They get the data from Redis and use Redis to communicate between all instances.
Of course, this is as well the final result. With using Redis instead of Firebase some things changed along the way.
I set up a VM with Ubuntu to simulate the Redis server. The frontend and the backend ran on the same machine on different ports. This worked quite well and didn’t change so far.
Front- and Backend are just node packages so they are pretty easy to maintain. New changes and updates can be deployed via now and are pretty straight forward.
Redis and Stunnel on the other hand, are a bit harder. I created service files for each to start them with the system and restart them if they should fail. In order to maintain this, I wrote some simple bash scripts that update the service and config files as well as the certificates and private keys. Whenever they get changed the services will get restarted.
The first, thing I started with was the backend. For that, I created a new node package with npm init and added socket.io to its dependencies. I then added modules to handle Redis, users, user actions, the game loop and so on. At first I used an object-oriented approach, but I came to the conclusion that my code was shit and made everything again in a functional approach. I’m way happier with my code now and it is much easier to maintain. To test everything I wrote a small HTML file and simulated games in the browser console until it was good enough to implement in an actual frontend. One thing that should be noted is that I used to hardcode some variables that should have been in environment variables instead (things like certificates for Stunnel, Redis host and password etc.), switching to now-env made the code a bit simpler and even more secure.
Speaking of which, before I started coding I drew some sketches and made a prototype in Adobe XD. A lot of things changed during the realization but the result was convincing enough. Creating a web app with Next.js is pretty straightforward. The game state is stored in the root component and passed on to the children that need it. Display grid helped a lot in keeping the component hierarchy rather low, therefore no need for Redux or the Context API, yet.
Before I published my project I played some test rounds with friends to see if everything worked out. There were some bugs that needed to get fixed but the rest seemed pretty solid. More testing and feedback would be nice but I guess I’ll leave that up to you now :). nightlypoker.co
I’m glad that I started this project and brought it to an end. The number of things I learned during the making will be a great benefit for future projects which I can’t wait to start.