A whole colony of cats, running at 60fps
By Nikola Acimović

Hey there! Welcome to the very first Cat Colony dev diary. I’m Nikola, CTO at Hex-a-gon Studio.
Quick intro on us first. We’re Hex-a-gon, a studio in Belgrade making simulation games. Cat Colony: Dreamworld is our first title: a mobile colony sim where you build a home for a colony of cats. The promise that drives the whole project is simple: every cat is a real individual. Not a sprite on a timer, but an actual little agent with its own personality, moods, preferences, and opinions about the other cats. And there’s a whole colony of them living in your pocket, on a phone. This diary is about how we make that run.
The colony problem
Every cat should, constantly, do three things: decide what to do, feel how it feels, and keep track of how it feels about every other cat. Write that the obvious way, with every cat running its full decision the moment anything twitches, and the work piles up fast. It piles up in two very different ways, though, and only one of them is what kills you at launch.
The first is the per-cat work: scoring every option and resolving a mood, for the whole colony, many times a second. At the sizes we’re launching, that’s what actually melts a mid-range phone, and the worse half of it is the memory garbage all that work leaves behind, which the device has to keep stopping to sweep up. The frame rate tanks, the phone gets warm, and your living colony turns into a slideshow. That pause while the collector runs is the stutter players feel as lag.
The second is the relationships, and this one is patient. It grows with the square of the colony, not the size of it: fifty cats is barely a couple of thousand pairs, which a phone eats for breakfast, but push it to a few hundred and you’re into millions of checks a second. Today it costs almost nothing. It’s the wall we’re designing around now, so we never hit it later.
So the entire engineering story of Cat Colony is one question: how do you keep the feeling of a whole colony thinking and relating at once, while doing a tiny fraction of that work, with enough headroom that you never have to think about it again?
Thinking in heartbeats, not frames
The first move is to stop thinking in frames. A game renders about 60 frames a second, but a cat doesn’t need to reconsider its life sixty times a second. So we decoupled the simulation from the frame rate entirely. The colony runs on its own heartbeat, a steady low-frequency clock, and the rendering runs at 60fps on top of it. A cat re-evaluates its situation only a few times per second. The animation that makes it look alive still runs every frame, as usual.
This split is the single biggest lever we have. Because the heartbeat is tunable (we decide how much simulation happens per beat), we can dial the colony’s entire thinking budget up or down to fit the device. A faster phone can afford a faster heartbeat. A budget one gets a slower one, and the cats still behave correctly, just deliberating a touch less often. Nobody can see the difference.
What that means for you: the cats feel responsive and alive, but under the hood they’re sipping CPU, not gulping it.
Letting sleeping cats lie
Even a few times a second, a whole colony all making full decisions at once would be wasteful, because most of the time, most cats don’t need to decide anything. A cat that just started a shift, or just curled up to sleep, has already made its choice and should stick with it for a while.
So before a cat runs the expensive part (scoring all its options, weighing its mood, checking distances and preferences), we ask a much cheaper question first: does this cat even need to think right now? The vast majority answer “nope, I’m good,” and cost us almost nothing. At any given second, only a handful of the colony’s cats are actually deliberating. The rest are simply living.
This is also what stops the colony from looking twitchy. Cats commit to a choice and live with it for a sensible stretch before reconsidering, the way a real animal would, instead of flickering between options every second because the numbers wobbled.
A brain without a body
One structural decision pays off everywhere. The part of a cat that thinks (how it scores a decision, how its mood resolves, how the colony’s economy ticks) lives in plain, pure C# code, completely separate from the Unity object you see on screen. The on-screen cat is just the body: the model, the animation, the little walk across the colony. The brain is somewhere else entirely, and it doesn’t know or care that Unity exists.
We did this for three reasons, and each matters more the bigger the game gets:
- It’s testable. We can run the entire decision-and-mood logic in isolation, with no scene loaded, and confirm that a cat with a given set of traits and a given mood makes the choice we expect.
- It’s fast. Pure data and pure functions are cache-friendly, and they let us run the whole colony’s logic without generating garbage every frame, which matters enormously on mobile, where the garbage collector is the source of the exact stutter players feel as “lag.”
- It’s extensible. Mood, decisions, economy, and relationships are each their own self-contained system, so we can add a new behaviour, or a whole new subsystem, without reaching into the others.
That’s what lets us keep shipping new depth without the whole thing collapsing under its own weight.
What that means for you: the cats get smarter and weirder over time without the game getting slower or more fragile.
Why we skipped ECS
If you know your way around Unity, there’s probably a question forming. The usual answer to “I have hundreds of things that all need to update” is ECS, the data-oriented setup Unity ships for exactly this kind of scale. It lays your entities out in tight rows of data and rips through them every frame, thousands at a time, without breaking a sweat. So why are our cats plain GameObjects?
Because ECS answers a problem we don’t have. It exists to make looping over a huge number of entities fast, and everything in this post so far has been about not looping over a huge number of entities. The heartbeat means the colony thinks a few times a second, not sixty. The eligibility check means only a handful of cats are ever deliberating at once. The social graph only touches the bonds that matter. Add it up and the expensive part of a busy frame is a few cats reconsidering their afternoon, not the whole colony. There’s nothing there for ECS to speed up.
It would also have cost us to adopt. Cat Colony is our first game, and ECS is a different way of writing almost everything, with its own rules for how data and logic fit together. Committing to all of that up front, for a colony sim a phone already runs comfortably, means paying a steep tax to fix a bottleneck we might never reach. For this game, at these sizes, it’s overkill.
It would have fought how we actually work, too. Cat Colony didn’t start as the thing you see now. It began much smaller and simpler, and we grew it: one cat became a few, a flat to-do list became moods and opinions, plain proximity became a social web. Regular GameObjects and pure C# let us turn that crank quickly, reshaping a whole system in an afternoon and watching it run. Locking ourselves into a rigid data layout early would have made every one of those pivots slower, right when moving fast mattered most.
None of this is a knock on ECS. It’s a great tool, and the day we want tens of thousands of something on screen at once, we know exactly where to reach for it. The brain-and-body split even means we could move the heavy logic onto it later without touching the cats you see. For now, the cheapest way to run hundreds of cats turned out to be not doing the work in the first place. A plain GameObject keeps up fine when it has almost nothing to keep up with.
It’s complicated
Now the hard part: the relationships. A real colony isn’t fifty independent animals. It’s a web. Cats spend time near each other, form opinions, prefer some companions and avoid others. That web is what turns fifty agents into something that feels like a society. It’s also the part that scales the worst, because it grows with pairs of cats rather than with the number of cats, and pairs pile up fast.
The trick is to refuse to compute all of it, all the time. Two cats only develop a bond by actually spending time together, so we only ever spend cycles on the relationships that are genuinely forming. And we let the whole web update on its own slow clock, well below the rate at which individual cats think. A cat’s fondness for a colony-mate doesn’t need to be recalculated sixty times a second, or even once a second. It changes slowly, the way real fondness does. By keeping that social graph sparse, tracking the bonds that matter and spending nothing on the ones that don’t, the relationship web stays cheap even as the colony fills up.
Two cats, one sunbeam
All of this machinery exists to enable the part we’re most excited about: emergence. When the systems are right, you get behaviour nobody scripted.
Cats already choose their own jobs and their own homes. Nobody assigns them. They weigh their personality, their mood, and their preferences, and decide for themselves, and you’ll catch one wandering off to pick a job simply because it wanted to. Another piece we’re building into the simulation is what we call rendezvous: two cats who’ve grown fond of each other deciding, on their own, to go and do nothing together, to find a warm spot and just hang out.
We didn’t hand-author “Whiskers and Mochi are friends.” We built the conditions, and friendship fell out of them. That’s the whole reason to do simulation properly instead of faking it: faked depth gives you the same scripted moment every time.
Real depth gives you stories you didn’t write.
Until next time!