Counterclockwise
It’s July 4th, and I’m sitting with my family at a mahjong table. The edges of the table are raised to make sure the candy-like tiles don’t fall off. My fingers brush along the synthetic felt as we shuffle the tiles. The tactile clacking of tiles as they are pushed into each other signals the start of everyone building their part of the wall. Dice are rolled, tiles are dealt, and the game starts counterclockwise.
I never really thought about it before, but most games I’ve played growing up operated in a clockwise fashion. Poker is clockwise, Catan is clockwise, Uno starts clockwise. The eastern games I’ve played seem to go counterclockwise though. Mahjong is counterclockwise, Big Two is counterclockwise. I’m sure there are western counterclockwise games and eastern clockwise games, but I’d imagine Chess is played clockwise and Go is played counterclockwise.
Sik wu!! As the winds of our table started to wind down, I started thinking about how it would be fun to continue playing online with people that I couldn’t easily get together with on a whim. So I looked for webapps and platforms to play this Hong Kong variant of Mahjong and I didn’t find much. There existed some platforms for Mahjong Solitaire, some for the Japanese variant (riichi), but nothing really for HK mahjong (definitely none with any polish to it or in English).It was in that moment that I decided to build a platform to play HK mahjong online. Thus counterclockwise.cc was born.
It’s still in a very alpha stage, but the webapp is deployed. Today, you can play a game of Mahjong with three other people, but a lot of bells and whistles are still being developed before I officially announce a version 1.0 release. Please try it out and let me know what you’d like to see!
Some technical stuff
This is one of the first projects that I’ve publicly deployed. The tech stack is pretty simple, just a Python backend with React on the frontend. Game state is stored in-memory for now. The backend is deployed on fly.io, and the frontend is served through Cloudflare.
A good chunk was pseudo vibe coded, mostly as an exploration of how fast I could go with modern AI tooling. In between the vibe coded PRs, I made sure to manually mold the code into a well structured codebase that I was comfortable working in and maintaining. Now that I have this initial release, I think I will continue to work in this half vibe coded way for the frontend (because I’ve got less FE knowledge and doing it by hand would take me forever) and work on the backend manually (because I still like to human code!!).
Some things I want to work on next:
- The UI is a mess and doesn’t feel good to me. I’m still thinking about what the UI should ideally look like to support a game like Mahjong. I want to put in a table that the wall and tiles can be on, but I’m not exactly sure how I’m going to do that yet.
- The game flow/UX of claiming tiles, discarding tiles also needs to be worked on. I think there needs to be a timer of some sort to make sure the game flows. It’s hard when in-person the timer is just the next person discarding a tile, but virtually its a bit trickier.
- Sound. I think a real draw to Mahjong is how the the tactility of the tiles and the clacking sounds they make when they are placed on the table. I want to try and add this dimension as much as possible virtually.
- Game persistence is not implemented yet. Neither is scoring. Right now everything is just in-memory for simplicity but I’ll probably move to some combination of Redis and Postgres
- At some point I’ll probably want to do AI players (in case there are too few players on the platform) and matchmaking (in case there are too many players on the platform)
- Mobile friendly. I think the UI/UX will have to change dramatically (or maybe just be required to play in landscape mode). As of right now, the mobile experience of the webapp is not something I’ve specifically addressed.