Clojurescript HTML5 Tetris
For a while now I wanted to build my own version of Tetris as a fun side project. I had always planned to do this as an HTML5 Canvas game. The reason for this is that I have had experience making a game this way in the past and felt that it is an easy way to make a game. It's also great that it runs in a web browser meaning I can host it on a website.
One of the key challenges with working with Clojurescript is the issue of state. A game needs to store allot of state. The way Clojure and Clojurescript are designed is to be a stateless immutable language. The is a mechanism for storing state which is called an atom. At the time when I started building the game, I opted to store bits of state in atoms. Over time the amount of state that built up grew substantially and now this is quite a large amount of atoms in the application. This is something that I am certainly not proud of as it majorly goes against the philosophy of the language.
One way I have thought of to rectify this issue is rather than storing all that is variables, I could pass my main render function an object containing all of the state. As that function runs though it could make changes to this object. Then at the end, it returns a new state object that can then be passed back in on the next render. In hind site, I feel like this is how I should of build the game in the first place. Retrofitting this now would be a challenge.
I'm very happy with the end result. It performs well and works in all modern browsers. It also scales well to mobile. It's fun and feels reasonably comparable to some of the original Tetris games.
I would like to build an online scoreboard for the game. At this point, I have not decided the best way to do this. I would like to make the project completely Clojure based but I have a niggle. I'm hosting this on a web server that fully setup for running PHP. It seems a little crazy to build the backend in Clojure just for creating a little database API when I have PHP already running and PHP can do this well. If I do it in Clojure I have to run a JVM on my server running the Clojure server instance, then I have to configure my webserver to proxy the API request to the Clojure application. This isn't a big deal and is probably the route I will go down but it just feels a little overkill.
Please have a go at the game:
If you are interested in the code, It is open source. Check it out on Github.