Autochess Of Ages: Project Story

Inspiration

Three things I love collided into one idea.

The first is chess. I grew up with it: the board is tiny, the rules fit on a napkin, and yet what can happen on it is effectively infinite. What I love is that nothing is hidden and nothing is random, so everything that goes wrong is my fault.

The second is auto battlers. They take the opposite bet: you don't control the fight at all. You manage your money and you arrange your soldiers, you press ready, and then you watch your decisions play themselves out for thirty seconds. It's chess with the tactics removed and the strategy left intact, plus a shop, plus eight players fighting over the same limited supply of units. If I buy the last copy of something, nobody else can have it.

The third is ancient warfare. I've always been fascinated by battles fought before gunpowder: Romans, Gauls, Teutons, the whole business of lines, flanks and morale deciding things before a single sword swing mattered. I'm currently reading Ad Astra, the manga about Scipio and Hannibal, and it's the purest illustration of what an auto battler is: two commanders who cannot touch the fight once it starts, and who therefore win or lose entirely in the preparation.

So: an auto battler set among ancient civilizations. Romans, Gauls and Teutons so far, more planned, each with its own bonuses, fighting on a hexagonal board.

And then a fourth, less romantic motivation. I wanted a real excuse to learn how online multiplayer actually works, with a server I run myself, on a machine I rent and maintain. Not a service that hides the difficult parts behind a convenient button. The database, the matchmaking, the match simulation, the certificates: all of it mine to keep alive.

What it does

Autochess Of Ages is an auto battler built for phones, made in Godot:

  • eight players per match, a shared and limited pool of units, three copies of the same soldier merge into a stronger one, and a shop whose offers improve as you level up
  • a hexagonal battlefield instead of a square grid, so every unit has six neighbours and positioning has more nuance
  • civilizations and their synergy bonuses are defined in plain data files, not in code
  • heroes with unique abilities, chosen before the match starts
  • single player against a bot, and real online multiplayer against other people, with matchmaking, ranking, a leaderboard and a match history, all running on a backend I host myself

Underneath it all there's one rule I never broke: the game rules know nothing about the screen. The simulation is a self-contained piece of logic with no idea that a 3D board, a shop or an animation exists. Everything you see is just a reader of what the simulation decided. That sounds like an abstract nicety, but it's the reason almost everything else in this project was possible.

How I built it

It went in fairly clean phases.

1. The game, offline first

First a playable single player loop: shop, bench, board, rounds, a bot opponent. Every balance number (costs, health, gold income, experience curve) went into a separate data file from day one, because I knew I'd be adjusting them hundreds of times and I didn't want to go hunting through code each time.

2. Same seed, same match

Before touching networking at all, I made the game reproducible: give it the same starting number and it plays out identically, every time, on every machine.

I even wrote my own random number generator, because the built-in one makes no such promise across versions and platforms.

That is also why my balance numbers mean anything: I can replay the exact same match after changing one value and see precisely what the change did. And it changed what a battle is: instead of returning a winner, it returns a diary of everything that happened, who moved where, who hit whom, who died, at what second, and the game replays that diary to show you the fight.

An automated check confirms the replay ends exactly like the original. That's the trick that later let an online player watch a battle their phone never computed.

3. Multiplayer

Built and tested locally first, then deployed. Online, your phone is never the one deciding: it sends what you want to do, the server validates it, simulates the round and sends back the result.

And it never receives things it shouldn't know. Another player's gold, their shop, their bench simply aren't in the message. They're not hidden in the interface; they're not sent at all.

4. My own backend

I started on a hosted service and moved away from it: database, matchmaking, match simulation and the web server all live on the same box.

The game talks to exactly one address of mine, and the only outside service left is Google, for login.

5. Balance as an experiment, not an opinion

I wrote a tool that plays hundreds of matches between bots, with no window, as fast as the machine allows, and reports how each unit and each civilization performed, measured with the same counters that real matches use, so simulated and real numbers are directly comparable. One single rebalancing pass ran 10,000 matches to justify a handful of numbers.

Another tool splits that work across several instances at once so it finishes in minutes rather than hours.

6. Everything around the game

Login (Google, email and password, or as a guest), an in-game guide, match history, a ranked leaderboard, sound and music, a crowdfunding store, the Android build, the Windows build, privacy pages, translations.

Challenges I ran into

Too many challenges to list, so here are the ones that mattered.

A round that has to end, but still has to finish

Every round has a time limit, otherwise two tanky teams would stare at each other forever. But late in a match, with full boards, a fight that simply runs out of time is unsatisfying, because nothing was decided.

So the battle keeps two clocks. One is the clock the round bar shows you, which always runs at normal speed. The other is the clock the soldiers themselves live by. Past a certain point, the soldiers' clock starts running several times faster than yours: attacks, movement, cooldowns, all accelerate, while the bar keeps filling at its honest pace.

I called it "Berserker Mode", and fights that were heading for a stalemate suddenly resolve.

Balancing the units

Making sure no single unit dominates took more iteration than anything else in the project, and the simulations only take you so far: they play the game the way bots play it. Real players will find combinations and strategies no bot ever tried, so what I have now is a solid starting point rather than a finished answer. No unit is far stronger or far weaker than the rest on day one, and from here the tuning follows real matches instead of simulated ones.

Managing how often each unit shows up in the shop

To keep the shop fair and predictable, every unit has a base chance of appearing, and the game adjusts that chance as the match goes on. It stops units from becoming unexpectedly rare or annoyingly common, and it means you can plan around what you are likely to be offered instead of just hoping.

UI for different screen sizes

Mobile devices come in all shapes and sizes, so a consistent, playable interface across all of them was essential. Instead of hard-coding a layout for specific devices, I built a system that measures the space actually available and scales the interface to fit it. That is what makes the game look and feel right on anything from a small phone to a large tablet.

Maybe in the future, with a bigger team, I will design dedicated layouts for each format, but for now the dynamic one gives a good experience everywhere.

No artist, so the game had to be playable with no art at all

I didn't have a 3D artist at the start, and I didn't want the project to stall waiting for one. So the first version of every soldier was built in code out of basic shapes, boxes, cylinders, cones. Not beautiful, but instantly playable and instantly changeable. Later I brought a 3D artist onto the project, and the real models replaced those figures just by landing in a folder under the right filename. No unit ever waited on art to be designed, balanced or played.

Running the server on a VPS

There is no free way to host a multiplayer service, so for a game at its very beginning I went for the cheapest and most flexible option: a VPS, a virtual private server.

The downside is that it is a far more demanding setup than a managed service, and to be honest, if the player count grows a lot I will have to rethink the infrastructure to handle the load.

But in the first tests, with a handful of players, it works well.

Accomplishments I'm proud of

  • A real server, run by me. Secure sessions, reconnecting into a match after your connection drops, ranking and a leaderboard: the half of multiplayer that has nothing to do with gameplay and takes most of the work.
  • Adding a whole civilization takes no programming. A few entries in a data file and enough units to reach the bonuses I declared, plus a check that complains if the roster is too small to ever reach one. Three civilizations and 21 units so far, each unit with an ability of its own.
  • Roughly 10,000 simulated matches behind the balance numbers currently in the game.

What I learned

  • Heavy use of Claude AI. I leaned on AI agents for a large part of the code and the architecture, which let me spend my own time on design and gameplay instead of on repetitive work.
  • The power of Godot. This was my first project with it, and it turned out to be a remarkably capable engine for both the 2D and the 3D side of the game. It also let me build for every platform I targeted, so I could concentrate on the game itself.
  • Reproducibility is something you buy early or not at all. Writing my own random number generator on day one felt excessive, and it turned out to be the thing everything else rests on. There is no adding it afterwards: by then the project has made a hundred decisions that assume it isn't needed.
  • "The server decides" is an architecture, not a setting. It means the player's device genuinely cannot compute the answer, and it means deciding, piece by piece, what each player is allowed to know.
  • Running your own backend teaches you the boring 80%. Services that restart on their own, certificates, database migrations, retrying webhooks that must not double-count, least-privilege accounts, session expiry. None of that appears in a game tutorial.

What's next for Autochess of Ages

I have plenty of ideas for where to take the game. These are the ones I'd start with:

  • More heroes and more units with active abilities. A bigger roster makes the game richer and more strategic.
  • Better balance, driven by data from real player matches, since people play very differently from the bots in my simulations.
  • More complex battlefields. Varied layouts and special scenarios would add depth and challenge: cells with obstacles, traps, or environmental effects that change how a fight plays out.
  • A campaign mode. A structured series of battles with a story running through them, for a richer single player experience and a chance to learn something about the real historical events and battles behind it.

Built With

Share this project:

Updates

Submission history