I Spent 47 Days Making a Game That Lasted for 30 Minutes

Once a month my coworkers and I play a game together. This is the story of a game that I worked on for 47 days, a game meant to be played for only 30 minutes at one of those sessions.


My turn to host our team’s online “Social” was on May 28, 2026. Far in advance, I already knew what I wanted them to play. This game was just an idea in my head, but no matter: I figured that I could manually “run the game” by hand using ChatGPT.

My personal philosophy is to first do a thing 100% manually, then semi-automate it, then fully script it. Usually the “manual version” is good enough. So it was settled: I’ll make my game idea come to life as the jankiest manual version of itself.

The game I had in mind

The Dark Lord, and Anubis-looking dude

We are all in a Hell Dimension.

Monsters from all over the galaxy have gathered to battle each other on a desolate planet, under the eyes of a Dark Lord.

Each player picks a noun and their monsters’ image is AI-generated from it. Players are encouraged to choose a silly noun – so you may get a “bubblegum monster” or an “old shoe monster”.

The monsters do battle, with each player typing in attacks as fast as they can for 25 seconds. Finally the Dark Lord (really a ChatGPT adjudicator) looks at the monster’s images and attacks to decide the winner.

Here’s the twist: the winner absorbs the loser.

After the battle, a new monster is created. The new monster is made up of 75% of the Winner’s body and 25% of the Loser. The losing player continues to be part of the new creature. This duo will then fight in a 2-on-2 battle against another duo (with their own composite monster). The “winner’s” attacks are weighed at 75%, but the previous round’s “loser” can still contribute to victory at a 25% weighting. And so on for smaller fractions at future rounds.

The game concludes with an everyone-against-everyone brawl that’ll synthesize the final winner.

Proof of concept

On November 28, 2025, I went ahead and checked if this idea was even feasible. I had ChatGPT do the following:

  1. Generate two monster images,
  2. Decide which one would win in a battle, and
  3. Combine them at a 75/25 ratio into a new monster

The concept looked feasible:

We were in business, baybeeeee!

Are we truly in business, baybeeeee?

I couldn’t think of a way to manually run this experience over a Zoom call. Like, I could collect nouns from roughly 12 teammates, generate initial monsters for them and then what? Make pew-pew noises while they watch me screenshare a ChatGPT session?

I guess I’ll have to build a multiplayer game.

On April 10, I started coding.

Time for tradeoffs

Dear Reader I’ve nevor made a multiplayer game in moy loife.

I’ve only made 1 game before. While it catapulted me to the top of the “violent canal-boat games” category, I built it with the Godot game engine and I had no clue how to use Godot for multiplayer games.

May 28 was fast approaching. The pressure was on, but my work schedule had recently changed in a way that juuust gave me a chance to finish on time.

It was feasible because this game was going to be a home-cooked meal.

The fact this game was meant for a specific group of people meant that I could skip certain challenges:

  • Scaling – only between 10 and 16 people would be playing.
  • Logins – no need for logins or passwords.
  • Anti-cheat – this wasn’t some competitive Counter Strike game. Nobody was cheating (and if they were, it would be fugging awesome!)
  • Sleek design – this game could be real rough, because it’s charm was going to be in the fact that I hand-created it specifically for my coworkers.
  • Asset hosting – our Team Social will last only 30 minutes, so I didn’t have to worry about storing the monster images. I could just hotlink to the images that my chosen AI platform generates – these image URLs each had an ample 1-hour lifetime.

Funny enough, the unpolished look of the game made it feel like a “quick and simple” creation to me (and I know it was neither!). My programmer sister, immediately picked up on the tonne of work that went into this game, though.

I chose not to vibe-code this thing. Partly because I don’t have experience with coding harnesses. Partly because I wanted to put my own energy into this game so it felt like a gift to others. Finally, I wanted to learn some new technologies and you can’t learn if an LLM is doing all the work for you!

No regrets here. Although there was a tetchy night with just 4 hours of sleep right before the deadline.

Me learn little

I’m a strong believer that you should “only have one crisis at a time”.

You could rephrase this as “learn one new thing at a time, while keeping everything else familiar”.

For this project, that meant running the game on my existing – NEARLY UNLIMITED – $90/year shared hosting (affiliate link because I’ve been with them since 2008 and this is what love feels like).

This dictated that I use a “polling” architecture where each player’s computer repeatedly hits the server for updates, instead of a more appropriate WebSockets/Sockets.io approach where the server proactively sends updates to the players only when an update is available.

I also leaned heavily on Python, and SQLite which is my “comfort zone database”.

The 3 new things I decided to learn were:

  1. Building multiplayer capabilities into an app
  2. HTMX: an easy way to do polling, and to make use of data from the game server
  3. Using AI APIs throgh an Inference Platform (I chose Replicate.com)

Hot take: Git is awful version-control software.
If it takes everyone a lifetime to understand the mental model of a tool, then it’s been designed very badly. I don’t care how pretty the internals are or that 100 tiny Linuses created it in 1 night while dancing on the head of a pin.

I ended up using “Fossil” version control for the first time. But as an amateur from the “just use CTRL Z as version control” school of programming, I still don’t understand the benefits of it. Finally, I had to learn Mermaid as that was the easiest way to visualize the tournament brackets.

Things that happened along the way

Here are some interesting parts of the 47 day journey:

Everything’s a Chinese Dragon

Initially, I was using “prunaai/z-image-turbo” to quickly generate monster images. But it was really difficult to get the look I wanted. Here’s an example of tweaking the prompt to generate a “crystal goblet monster”:

All the monsters had a particular look. Eventually I thought maybe this image generation model was trained in a way that biases it. Turns out that the Z-Image foundation model was created by Alibaba’s AI division. They must’ve used a lot of images from China during model training, as well as lots of e-commerce imagery. That must be the reason why all the monsters look like Chinese Dragons and/or product hero-shots!

I ended up switching to Flux.2 Pro. That one was created by Black Forest Labs, a German company. Their images more closely matched my concept of a monster. It’s interesting to note that this means my aesthetic preferences have a Western cultural bias.

With all generative image models, I found that some concepts are so strong that they completely override my prompting. As an example, an “owl inspired monster” would strongly snap to being… just an owl:

Attempts to create an owl monster mostly ended up as just an owl. Similarly, some models spotted the word “predatory creature” or “alien being” and would generate monsters that looked identical to the Predator and Alien movie monsters.

I had to put lots of work into the monster-generating prompt. It had to be generic enough to work with any noun, but also consistent enough to give a certain look. This won’t be surprising to anyone who frequently creates AI images, but it was eye-opening to me (or maybe eye re-opening, as I’d previously used Midjourney and all the prompt tweaking was exhausting).

Click to expand the final monster-generation prompt I went with.

Here is the typical look of the monsters this prompt generated:

Notice that they’re all bipedal lizardy dudes, framed by the background on boths ides, have the right number of limbs and 5 fingers on their hands. It’s a very standard look and I would use more extreme random elements in the prompt next time (“3 hands”, “a horn coming out of the chest”, “spraying acid”). The look came out a bit vicious. It would’ve been better for a game with coworkers if it was more goofy and lighthearted

Adjudication took longer than expected

I thought that, after a battle, deciding on a winner would be quick and my players could read through the decision right away (with the slow work of generating a composite monster image happening in the meantime).

Things worked out the opposite way.

The Dark Lord takes his sweet time to declare a winner

In case of timeout or error, I made the Dark Lord choose a winner at random and say “X wins, because I like the cut of their jib and don’t owe anyone an explanation”. A simple solution for rare errors in a 1-time game!

For some reason, OpenAI’s GPT-5-nano and GPT-5-mini would take 15 – 30 seconds to analyze the monsters’ images and attacks while generating a decision in the Dark Lord’s style. This slowed down gameplay significantly.

In contrast, combining multiple monster images into one only took 13 – 17 seconds. I believe that it’s the analysis of 2 or 3 monster images that slowed down the adjudication. In the end, I chose to use Google’s Gemini-2.5-Flash model for generating the final decisions – it took only 5 – 7 seconds.

Adding some spice

I’ve already listed the things I could remove because this was a game for one group and one time – scalability, authentication, etc.

Towards the very end, I realized that I could add certain in-jokes for the specific individuals playing the game. Each monster had a semi-random name and I made the name sometimes end similarly to a team member’s name. So it would sound eerily familiar but not quite.

Monster name suffixed that would appear 1 out of 25 times

In retrospect, I should’ve made these suffixes a lot more probable. After all, we’re playing this game only once together!

Did my tech choices work out?

With 20/20 hindsight, if I were to build this game again I would’ve upgraded my hosting to a VPS so I could have long-running apps and use Socket.io.

Socket would let the server inform the players when there is a game event / new command to run. I had to build a polling system instead, and that was unnecessarily time consuming. I believe Socket.io would’ve also helped with synchronizing the “current time” between the server and players, to avoid key events like Battle End happening at different times for different people.

I liked HTMX!
I never understood the hassle of having the server send JSON objects that then influence the HTML structure of the page. HTMX cuts all that out by having the server respond to REST requests with a finished HTML fragment, that the client then jams into the existing page.

In case you’re curious, the last programming language I actually liked was Perl 5.

I still hate Python but I’ve gotten more comfortable with it because of this project. So, maybe I hate it a little less now?

The final battle: everyone against everyone

Replicate.com was a good tool for testing and switching AI models quickly. Kudos to my sister for educating me about OpenRouter and similar middleware. Replicate made it a breeze to call a variety of AI APIs, a big benefit to the project.

What I didn’t like about Replicate how difficult it was to find a suitable AI model for a given task. Their UI is unusable for this (they provide marketing-speak instead of a comparison of features/speed). I had to use artificialanalysis.ai to choose models for the project. I also didn’t like that Replicate throttles their API usage unless you set up auto-deposits to top up spend. This wasn’t called out upfront and their documentation showed conflicting figures for the amount of preloaded cash that lifts the throttle. Finally, I thought that I’d be able to use one simple API for all models on Replicate, but each one required slightly different parameters and setup. None of these were deal-breakers.

Was the outcome good?

Yes!

The whole team and I played the game and we had fun.

I’m very satisfied with what I built! Visually, the game came out looking very Boris Vallejo (NSFW) / “pulpy” because of the font and the classic hero-stance of the monsters.

The tournament ended and the final monster is born. The player with the “Fluffy” monster is the winner – because their original monster constitutes the biggest portion of this final creature.

The beauty of throwing your life away

Isn’t it funny to spend so much time on creating a 30-minute experience?

On projects like these I am usually torn between two feelings:

As a creative man I often feel like life is slipping away from me. With 2 kids occupying evenings and weekends and a full-time job, I would have to make brutal decisions about how I use my free time. This was especially relevant prior to April, when I’d had only ~2 hours free for projects after the kids went to bed (in practice, this often meant a lack of sleep for me).

But also, I find that these projects – where the effort is comically disproportionate to the output – are the most satisfying to undertake (and read about! obligatory Mehran’s Steakhouse mention). I get to learn something new and, ironically, the noncommercial nature of the project gives me the stamina to carry it out to completion.

Ultimately silly projects like “Monster Mash” are what abundance looks like. They are undertaken out of curiosity and generosity.

Besides… this “1.5 months for 30 minutes” project is a marked improvement over my last game: that one took 3 months for 3 minutes of gameplay!

“OK Jacob, I really wanna play it now”

If you’ve fallen in love with the Hell Dimension Extended Universe, and you’re a loyal reader of the blog (disloyal readers will be chased out!) then reach out to me and I might set up some games for you & your friends/colleagues. No promises.

As always, I’m <my first name> at <this website>.

Adjudication for one of the initial 1-on-1 battles.


Get monthly updates. Who’s dating whom on the blog? Who’s my baby’s daddy? Pinocchio vs. Pinochet who wins?