Building an online Poker Game. My journey to completing a MVP!
Recently I went a bit crazy and had a need to create something. I decided to go back to a project I had attempted a couple of times in the past. A working Online Poker game.
My Background
A few years ago, I was employed as a back-end developer for a large financial system that was many millions of lines of code. Since then, I have been working in IT as a Business Analyst or Project Manager.
I've always loved coding, and I'm always happy when I get a chance to focus on it. The following is a high level review of the challenges and triumphs I experienced getting to the MVP for this project.
Day 1: 17-Sep
First, I had to learn how to build a game in html5. I started where we all should, Googling how to do it.
From here I learnt about something called canvas
.
Alright! Let's try that. Cool it's like any 2D graphics interface, this will make life easy! -- This is what I always think when finding new tech before I start running into problems.
First, an example to start.
Nice. That gives me the base methods I need to call. Now to workout how to get display images of cards. This is what often stumped me back in the day. But, within an hour or so, I read about the drawImage()
function that can draw a sub-part of the image. With a little bit of maths, I have pictures displaying!
Good job so far! Now I've created the local git repo using SourceTree. I love those tools.
I also found this video series on YouTube of a guy building simple games in 30 minutes for inspiration. Excellent! They use a framework that i couldn't see any reason behind using.
Time for some buttons.
Great! Let's get the cards on the table.
Notice I still have the slow moving ball to indicate things are still running :) Hmmm. I can see that the card dealing is far from perfect given the repeat card. That doesn't matter at this point though. Eventually these cards will be coming from the server, not just the browser.
Alright, looks like we're ready to start speaking to the server.
The Server
Lucky for me, I have a few websites that I've mostly started, and a couple I've completed. I have a Slim 3 REST Framework on my writetoday.info domain, a domain I still haven't used. Perfect.
The meaning of life
XMLHttpRequest cannot load http://external.service/. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://my.app' is therefore not allowed access.
So... Why isn't this working? It turns out you cannot read data from a REST call that is sent from a different domain. What this means is the code has to be on the same server and url as the REST API to be able to read data. This took me a good 2 hours to work out. Painful.
Eventually I have XMLHttpRequest()
on code hosted on the same domain. Very good.
I've made it work at least work locally.
A bit of reading late, it's late. That's it for today...
Day 2: 18-Sep
The game is starting to take on a basic shape now. A lot of the work is being done in the client, it is keeping track of the game and it is requesting updates from the server via REST. Not ideal, but I'll get the UI operating.
Cool, kind of working!
The Server
Uh oh... I can't keep variables across sessions. I have to get the database working. After 1 dumb question to StackOverflow (+3 reputation) about PDO connections errors, I'm storing what I need in the database.
Uh oh... This is starting to get really complicated. I can't stop the same card from appearing more than once.
Sigh, not a great day, I'm already running into situations where I'm having to do workarounds.
Day 3: 19-Sep
Start with the server today. Seriously, why are cards appearing twice?
WHAT?! Apparently in php, the language that Slim 3 Framework is built on – Global Variables are NOT available to Local. I've never heard of this in any language before.
I stuff $this->
throughout my code and go from there. I still don't have a way to effectively store variables between sessions. I learn about Memcached
, but I cannot get it installed and working on my server. Off to stackoverflow and gaining +15 rep for a question about how (it turns out) I cannot write numbers properly! This won't be resolved for another couple of days, I need another solution.
Now I start working on serializing
to put the objects into the database and get it mostly working. This is starting to get really ugly.
Getting pretty sick of this... You know what... I give up. I'm having to work around the language and the solution. Server side is a failure and the client is overly complex.
START AGAIN
Day 3: 19-Sep - Part 2
Now I've done a lot of reading on how to work without REST, it was a nightmare to get Slim 3 running, and I'm really not wanting to deal with Sessions disappearing. It's the wrong solution.
And then I learn about WebSockets, an amazing full-duplex technology built on TCP, it even works over cross-domain!
Alright, time to swap. I know I should throw away all this code and start again, but that feels hard in the short term. The Server is a complete throw away.
I find a new PHP library for WebSockets, easy enough. The WebSockets php app runs indefinitely, creating new connects by Upgrading connections with Handshakes as they come in.
An hour later, messages are being sent back and forth. Another hour more and I'm sending it in JSON format!
My message test console
Visually nothing has changed
Long day today.
Day 4: 20-Sep
Server is now at a point where I can start structuring the code a little more nicely. Unfortunately, it is a bit unreadable with the $this-> on every single variable and just generally how it has been done. I wonder if there is a framework to help clean this up? Back to stackoverflow to find out if there is a framework. -15 reputation points later, I write my own precompiler to make this language more manageable.
I look into some other server technologies. NodeJS, Ruby on Rails. I haven't found any reason to think they'd do a better job. I mean, they would, but I can't see a reason to throwaway this MVP code (therefore ultimately throwaway code) yet.
The project is now sufficiently complex that I need to write scripts to deploy code with calling the precompiler routines and start running the server. Eek...
The Client
Finally I can throwaway all of the garbage "Local" code I had to write to develop with REST. It looks like it has gone backwards, but the client is now Online Only!
Today was a really pleasant day on the progress. A stark contrast to the pain of day 2 and 3.
Day 5: 21-Sep
Today the Client went on a diet! All of the Game State information is now the domain of the Server, the Client shows the user what it knows, and what it knows is not a whole lot.
And also it was fattened up again. With a working seat available mechanism and a seat leaving mechanism installed!
The server is now practically decoupled from the Database until I actually have something to store. All the server state is stored comfortably in objects in the server app.
Stackoverflow helped me solve the Memcached
issue. I was installing the wrong version. Hah.
Day 6: 22-Sep
Big dayyy. Removed all of the Database today! All that code I did as an original workaround, gone. Serialization will be a useful lesson for later.
Today was the day I discovered that "JSON" stands for "magic". I can define a class on the server, and use that class on the client side with no redefinition! Once I found out how powerful this is, everything has become JSON.
The client is now a receiver. Up until today there were some messages coming from the client that would cause the server to respond. This is all decoupled now. The server can send whatever whenever, the client can send whatever whenever.
I'm now in the homestretch! I'm taking care of game issues, not just technical communication issues!
Day 7: 23-Sep - Release Day!
So this is it! The functionality is all done now. It didn't take much longer than I expected, and I have learned a lot. I've learned details about REST, some Javascript technologies, a lot of PHP, and as always, a ton about maintaining and running a server.
Aftermath
It turns out that I didn't leave the project long. Since then, I have converted it to No'Limit, added graphics, increased stability, improved login/logout, improved messaging, increased to 4 players.
Closing
At the time, I had an urge to create something, and I am really proud of what I have managed to achieve. I honestly can't wait for my next project like this.
If you'd like to see the latest version, it can be found here. I will probably write a little journey like this one on the gap between then and now.
Thanks for reading.
I love programming. Keep posting more of this! Following.