Reviving a Dead Pet Project

Back in 2017 I started what a smart-ass commenter on Hacker News could’ve done in a weekend: I started working on a pet project. A browser game implementation of a rather complex traditional German card game called “Doppelkopf”.

I didn’t have huge goals for the browser game back then. I had started playing Doppelkopf with friends in Hamburg regularly and noticed that my game just wasn’t up to snuff. Being a smart-ass software developer myself I knew the obvious solution to my skill issues: Build some software that can play Doppelkopf, and your own understanding of the intricacies of the game will improve. And hey, maybe some people out there get a kick out of playing this game while we’re at it.

I’m not as smart as apparently everyone else on the web. This endeavor did not take a weekend. Even a handful of weekends didn’t cut it. I worked on it in teeny-tiny chunks, whenever I had a few minutes to spare and ended up building something somewhat usable over the course of years. I wrote about it back in 2017, published my source code on GitHub, got some pretty cool open source contributions (thanks folks 🫶) and ended up with something that implemented about 70% of the entire game’s gnarly ruleset.

Then I ran out of steam.

Key features remained unimplemented. Despite my best intentions to solve those one day, I just couldn’t get myself to continue. The code base was in a decent enough shape, mind you. It’s obviously far from perfect but test coverage was pretty good since I TDD’ed the entire thing, which is what allowed me to have such a long run to begin with. The problem was that I hadn’t anticipated the last remaining features in my initial designs and implementing them would’ve required a substantial overhaul of the code’s design. I couldn’t get myself to spend any spare brain cycles thinking about how I’d pull that off. My work as a software developer (or engineering manager these days) makes me think about software and systems all day, 40+ hours each week. While this pet project started as a creative outlet that allowed me to explore new technology just for shits and giggles, eventually that become more and more of a chore. I was trucking along because I wanted to complete what I started, not because I enjoyed the process any longer. It felt like just another job, without anyone paying me to do it.

Sometime around 2022, after months of merely picking low-hanging fruit, I ended up leaving the project in its half-finished state and walked away from it. Not over night but rather as a slow and creeping process.

Somewhere deep down, the thought that I didn’t manage to finish this damn thing haunted me whenever I thought about it. Without the game being complete, nobody would really get much of a thrill out of playing it. While building this project I got a much bigger appreciation for what this project could be: Besides getting a stronger grasp for the intricacies of Doppelkopf, I sensed that — if done right — this browser game could really help a lot of people out there to get started with this wonderful card game and inspire them to socialize and start playing in real-life.

Fast forward to the end of 2025. I found myself with quite some time at hand. Having quit my previous job as an engineering manager recently I was taking a generous break before starting my new job in January. As an engineering manager I hardly got any excuse to write code anymore in recent months and I was craving the thrill of creating something from nothing once more. I had an explosive combination: A desire to create and plenty of time at hand to focus and build.

I decided that it was time to revive my dead pet project.

I don't wanna be buried in a pet sematary I don’t wanna be buried in a pet sematary

What initially started as an attempt at salvaging my old code base, upgrading a few dependencies, ironing out some quirks and doing overdue refactorings ended up in me throwing away everything and starting all over from scratch. Oh the beauty of a pet project, where you can commit cardinal sins without anyone giving you a hard time for it!

Rewriting the browser game was harder than I anticipated. My coding chops had gotten a little creaky after years of mostly working with squishy human problems most of my days. More importantly though, I spent the first three weeks trying to outsmart myself. “If I’m going to rewrite it, I’m going to do everything differently this time”, I told myself. Learning from the past mistakes that lead me to get stuck was a good idea. When rebuilding this thing I designed the new system with all the overhauls in mind that were difficult to retrofit into the old code base.

Ultimately I took the desire to do differently too far which and I ended up running in circles. Where I had a readable, useful and testable object-oriented domain model for the game’s core in my first code base, I wanted to take a more functional approach this time out of a silly desire to write more idiomatic TypeScript. Using classes doesn’t feel idiomatic in TypeScript, so pure functions and immutable data structures were my declared ideal. Implementing immutable data structures turned out to be a hassle that wasn’t worth it and doesn’t align with svelte’s reactivity system. Pure functions ended up being more convoluted than my previous object-oriented domain model that encapsulated state and behavior nicely. After a lot of trial-and-error I ended up where I started, with a good old object-oriented domain model utilizing JavaScript’s class syntax with a couple of functional patterns sprinkled on top where they help — turns out OO lends itself nicely to game development, who’d have guessed.

Once I’d found my stride, things started flowing nicely. I churned out a lot of features in a short time, obsessed over UI details and accessibility concerns, and ended up rebuilding the entire game from scratch but this time including the missing 30% of functionality. It was a blissful time and I ended up losing track of my days numerous times — time flies when you’re having fun.

I considered experimenting with AI-assisted coding to combat my current skepticism but decided against it. I was just having too much fun honing my own skills, sweating the details and being in a flow state and didn’t want AI-tooling to take the fun out of it, reducing my job to prompting and reviewing outputs. My progress might have been faster, who knows. Yet I’m certain I wouldn’t have lasted as long as things would’ve stopped being fun early on.

I contemplated a lot whether I wanted to build the new version as an open source project like my first attempt. As much as I believe in the positive things open source can bring, I decided against it. One thing I learned when building the first version is that collaborating with open source contributors who share your passion can feel refreshing, validating, energizing. Paradoxically at the same time it was probably the one thing that suffocated my own passion more than anything else. Suddenly you’re reviewing other people’s code, explaining your ideas so others can follow, discussing with people online. Suddenly your pet project feels more like… actual work. Now I could make the source code available and simply not accept contributions. But then I’m cautious of what happens with my code in this day and age (and it’s depressing that that’s how I think about it). With the large scale intellectual theft we’re seeing from current large language models, with repeated patterns of people and organizations trying to profit off of hard work other people put into their projects without ever giving anything back, I just don’t feel like I want to publish my work for others to make a profit. I don’t know if this project will ever turn a profit (secretly I don’t want it to — that’s once more where creativity stops and tedium starts), but if it does I want to be the one profiting from my own hard labor and creativity.

Good things take time. After years, this project is finally in a state where I’m feeling a sense of completion and accomplishment. Work, private life, and everything in between can make it hard to dedicate time to a thing you were once passionate about, and I’m glad to see that this passion ultimately came back with a vengeance. Creativity ebbs and flows, and creativity needs idle time and boredom to flourish. I was fortunate to have a couple of weeks of idle time and boredom and I’m stoked that I managed to use it to rekindle my passion. When creative endeavors start to feel too much like a chore, I think it’s better for the end result to step away until passion comes back. I just hope that next time it doesn’t take years.

I’ve got high hopes for this project and think it can become more meaningful than my initial, selfish attempt at becoming a better Doppelkopf player. It can be the home for thousands of people trying to pick up this delightful (yet notoriously hard to learn) card game — and I hope that I can give something back by publishing my project like that.

A poor quality demo - I need to brush up my screencast skills

My past few weeks have been pure delight. Creative juices were flowing and I completely lost track of time. I managed to rebuild the entire game, finally implemented all the missing features and snuffed out the nagging voice ridiculing me for never finishing this project. On top of that I built an entire website and interactive tutorial to accompany the browser game — and I sincerely believe that this is the best resource out there to learn Doppelkopf.

I don’t know where this project will go in the future, but currently I’m more motivated than ever to keep on building. I’ve got plenty of ideas jotted down, starting with making the game more accessible to everyone out there.1. There might be a multiplayer option further down the road, tooling for offline Doppelkopf players, and more. Fingers crossed that I can keep the current momentum alive.

In the meantime I encourage you to check out what I’ve built so far. My Doppelkopf browser game and interactive tutorial are out in the open since yesterday. It’s completely free and it’s super fun.

You can find it over at doppelkopf.club. Enjoy!

Footnotes

  1. It’s only available in German right now so you’ll have to use a translator of your choice for the time being, but internationalization is next on my roadmap, pinky swear!