The first commit of this project dates back to... *checks the git history... Blimey, November 2022!
Well, it looks like it took me only a year and a half of work to get it to a state where I can finally tag this repo with... 1.0
!
A chess game I've been thinking of for many years
I started to play chess online very casually 20 years ago, on a French website that no longer exists.
It was the years during which The Lord Of The Rings films were released, and me and my friends were very much into it; as a result,
I was a big fan of Heroic Fantasy at the time.
And as the game of chess is of course a game replicating a battle between 2 armies,
I was finding it a bit of a shame that what is supposed to be a battlefield was reduced to the abstract chess pieces' symbols we play with today.
Playing chess is great, but I was missing the epic dimension. ⚔️🛡️
There was also this open source game I was playing at the time, The Battle for Wesnoth: it had
really nice graphical assets, and I was thinking that it would be great to have a chess game with such a level of graphics. 🎨
But I was feeling that it would be way too much work for a solo project built on my free time, and this idea was never turned to a real project.
Playing chess with Zachary made me think of this project again
Fast-forward to many years later: I'm still a professional web developer, but even though I'm no longer using Flash I have other cool technologies in my toolbox, given by the wonders of the modern Web.
Intrigued by the many solutions inspired by Phoenix LiveView, it came to my mind that a good way to experiment with such solutions would be to build a basic chess Web game that would feature Heroic Fantasy characters instead of chess symbols, powered by such a framework behind the hood.
In October 2022 I went to visit a part of my family in France, and played a few chess games with my nephew Zachary - nicknamed "Zackou".
After years without playing chess at all, playing with him reminded me of this potential project... and a few weeks (and a covid 🤒) later, I was finally starting to work on it! 🔧
As my nephew "Zackou" was the one who game me the inspiration to try to get this project finally started, after all these years, the name of this side project would be... ZakuChess!
A game UI fully powered by htmx
The very first version was powered by Django Unicorn.
But even though it allowed me to get a working prototype in just a few hours of work - which made me think that I could build that project, so thanks for that Django Unicorn ! - it was still a bit immature at the time
(I came across weird bugs related to type hints for example).
I then gave a shot to Stimulus, as it's a library I've used in some projects at work and I kinda liked it.
However, I quickly realised that in order to have a fully working game UI I had to write a lot of business logic twice: once in Python on the backend, and once in TypeScript on the frontend.
That was a bit too much for me, given I was working on this project only a few hours here and there.
But there was this minimalist JavaScript library I was hearing more and more about, though, and I liked its promises: htmx!
So I quickly updated my early prototype to use htmx instead, and started to play with it.
After a few hours with htmx I found that it was a great fit for my needs, and I was able to
iterate quickly on a game web UI that was fully controlled by the backend.
At the end of the day, I still ended up having a part of the game being actually powered by frontend-side JavaScript,
which made the thing a bit more complex and less elegant than I would have liked it to be.
But overall I'm happy with the result, and htmx's mental model worked really well for me!
Playing against a 'bot' opponent: the choice of using a browser-side engine
As this game is hosted for free by Fly.io I cannot run the chess AI on the server - it requires way too much resources.
(I tried... and the VM instantly crashed out of memory 😅)
Which is why I have to delegate parts of the business logic to the Stockfish chess engine running in the player's browser, compiled in WebAssembly by the folks at Lichess.
Because of this, even though the vast majority of my business logic is on the backend, written
in Python and powered by Django...
I had to delegate a bit of it to TypeScript, which is in charge of handling the bidirectionnal communication between the backend and the Stockfish engine.
18 months later, the game is fully playable at https://zakuchess.com/, has been running live for a few months already, and as of today has no known bugs 🎉
I've had many side projects in the past, but this one is the first one I've actually finished, and pushed live! 🎈
The stack
I may revisit some parts of this later, but in its current form here are the main technologies used in this project:
- Programming language: Python
- Web framework: Django
- Database: SQLite
- Live user interface: htmx
- HTML templating: DOMinate (the closest thing to JSX I could find in Python 🙂)
- CSS framework: Tailwind CSS
- TypeScript compilation: esbuild
- Units art: The Battle for Wesnoth 🛡
- Chess logic on the server: python-chess
- Chess logic in the browser: Stockfish (compiled in WebAssembly by the wonderful folks at Lichess 💙)
- Talking of Lichess... Most of the daily challenges are adaptations of games from their open source database of chess games and puzzles, so let's double that heart: 💙💙
- Tests suite: pytest
- Hosting: Fly.io
I found that the combination of htmx and Tailwind gave me an excellent level of locality of behaviour: from my HTML templates I was able to control the game logic, the UI, and the CSS styling, all in the same place.
For a solo project I could only work on a few hours here and there, that was definitely a plus!
The whole thing is open source, and the code is available at github.com/olivierphi/zakuchess.
Are the Zakuchess battles epic enough?
Alas! I'm clearly not a graphic designer, so unfortunately the ZakuChess battlefield is not as epic as I was hoping it would be. 😔
I did the best I could to make it look not too ugly, and create a bit of atmosphere (the characters react when one of them is captured, for example), but it's still very far from what I would have liked it to be.
But hey, the game is open source, so... if you have such talents 🎨 yourself, please feel free to contribute! 💙
The relevance (or lack of?) of 1.0
I'm very happy to have finally finished this project, and to have it running live for a few months already - during which
I kept adding features as I was getting feedback from various people.
A huge thanks by the way to friends and family who tested the game at different stages, and gave me useful feedback on it! 🙏
Seeing it featured in 2 newsletters was a really nice surprise, too! 😊:
And even though this 1.0
tag doesn't mean much - especially since this is a standalone
web app, rather than a package that could be used by other projects...
It's still a nice milestone to reach, and this tag is the reward to my past self for getting this side project done! 😃