Finding a balance by running a hundred worlds

← All field notes

By early June the world had everything it needed to be alive: plants that grow and are grazed, a grazer that eats and moves, a fox, a corvid, a bird of prey overhead. What it didn’t have was a setting where all four held together. This is the story of how we found that setting — not by tweaking numbers until they felt right, but by measuring.

The trouble with a world this feedback-rich is that you cannot reason your way to its numbers. Turn one creature’s vulnerability up and you don’t just change that creature — you ripple through everything it eats and everything that eats it. We had the mechanisms; the precursor to this post, the equilibrium that wouldn’t settle, is the story of why a clean sweep of one of those mechanisms found only collapse or boom and what we shipped instead. This post picks up after that, with the question still open: does a stable, coexisting balance even exist here — and if so, how do you find it?

Four days of hand-searching one slow run at a time

The first method was the obvious one, and it was wrong. We ran the full world simulation, changed one value, watched what happened, and changed the next. Each run took the better part of an hour — thirty to eighty minutes to play out enough of a world to judge. So a day bought a handful of attempts, and every attempt taught exactly one thing: the next hidden interaction, which you only ever saw after the previous run finished. Every fix was individually correct; the systems were so tangled that being right about each piece never added up to a world that held.

We spent roughly four days like that. Then we stepped back, and the thing we changed was not how hard we searched but what we were searching with.

The slow world is an oracle, not a search engine

The insight was that the heavyweight simulation was the wrong tool for the job we were using it for. It is a slow truth-teller, not a fast explorer. Using it to hunt for good numbers is like asking the most careful person you know a hundred quick questions and waiting an hour for each answer — you’ll get the truth, eventually, and run out of days first.

So we built a second, lightweight thing alongside it: a fast model of the ecosystem, a set of equations that play out the populations directly. Where the full simulation grinds through every creature, every cell, every tick, the fast model asks only the population-level question — given these settings, what do the numbers do over the next few in-game years? — and answers it in seconds instead of tens of minutes.

We didn’t trust it on faith. Before we let it search for anything, we checked that it reproduced the behaviour of the slow runs we’d already done by hand — that where the heavy simulation crashed a population, the fast model crashed it too. Only once it agreed with the oracle did we let it lead. And we kept the division of labour strict.

Reason first, sweep to explore, and run the slow world only to confirm — never to search.

Running a hundred worlds at once

With a model that played out in seconds, we could do what the slow simulation never allowed: try many candidate settings in parallel, each run a different world, and read the outcomes side by side — effectively a hundred lightweight worlds running at once, each asking “what if this number were a little higher,” all answering in the time a single real run used to take.

The mechanism we were tuning is a gentle, rising pressure: the more crowded a species gets in one patch, the more vulnerable each individual there becomes — a soft local ceiling that keeps a population from running away without ever slamming a hard wall down. It has one knob per species — how dense that species can get before the pressure bites — and a couple of shared knobs: how steeply the pressure climbs, and how big a neighbourhood “crowded” is measured over.

We searched the way you’d search anything wide and unknown: coarse, then fine. First a broad bracket of candidate steepness values, low to high, to find which end of the range even produced a living world. Then a refinement around the promising end — three candidates clustered near where the coarse pass had pointed. It worked because the response is mostly one-directional: turn the steepness up and the population it constrains comes down, smoothly, so the search has a banister to hold. Most of the time.

The same voxel valley shown as a grid of side-by-side panels at golden hour, each panel holding a slightly different scattering of grazing animals.Concept art · pre‑alpha
Many candidate worlds, run side by side — each one asking what the populations would do if a single number changed.

The one knob that ran backwards

Most species behave themselves under that pressure. The grazer did not. Push the shared steepness too high and, instead of thinning the grazers, it culled the predators above them harder — and with fewer predators leaning on them, the grazers were released to climb rather than fall. The knob ran backwards through the food web: turn up the thing that should suppress prey, and past a point the prey go up.

That is exactly the kind of finding no amount of careful reasoning surfaces and only measurement does. We had assumed the response was one-directional everywhere, because for three of the four species it is. The sweep showed us the fourth, and showed us that the prey’s sweet spot sits at a middle steepness, not the highest one — high enough to hold them, not so high it strips out the predators that hold them too. (The coupling, and the living world it finally produced, belong to their own note — the equilibrium that finally settled.)


A carrying capacity is a density, not a head count

The deepest lesson of the whole effort is the one that sounds most obvious and is easiest to get wrong. A species’ ceiling is a density — how many fit comfortably in a patch of ground — not a target number of animals. Treating the two as one is a real trap: a head count that looks right at one world size is the wrong density at another, and a density that holds anywhere translates to a different count depending on how much room there is.

A carrying capacity is a density, not a head count — and conflating the two is its own kind of bug.

So we didn’t set each species’ capacity by picking a number we liked. We read it. We ran the world to the point where a species was sitting at the population we wanted it to hold, then read the actual local density off the readout at that moment — and that measured density became the species’ ceiling. An explicit witness, not an assumption that a target count could stand in for a target density. The number we wrote down was the one the world reported, not the one we’d hoped for.

We spent the cheap runs where they were cheap and the expensive ones where they mattered: shorter exploratory passes to find the shape of the space, longer confirming passes to make sure a candidate stayed stable across two or three in-game years. An in-game year is about a hundred and ninety days; a balance that only holds for a season isn’t a balance, it’s a slow crash you haven’t watched long enough yet.

Validate, don’t back-justify

The discipline that kept all of this honest was a single rule: every landed value had to pass its own check, not a check we built to flatter a number we’d already chosen. The easy failure mode in tuning is to settle on a value because it produced a pretty run, then reach for whatever measurement makes it look deliberate. We did the reverse — pick a value, run a test designed to falsify it, and keep it only if it survived.

An early guess for how often creatures breed is the clean example. The rate seemed reasonable, but a calibration run showed the population sliding below replacement — not booming, not holding, quietly draining away. So we rejected it and nudged the rate up to the gentlest setting that still grew: not the highest, the lowest one that didn’t lose. The run is what falsified the guess; without it we’d have shipped a number that felt fine and slowly emptied the world.

None of this makes per-species hand-tuning the final answer. The better long-term shape — letting each species’ ceiling be derived from its own local environment, so the world balances itself without a human dialing in every number — is where this is heading. But it was the wrong thing to force in now, with the roster of creatures still growing. What we needed first was a world that holds, found by measurement, with the method written down so the next balance is a sweep and not another four days of slow runs.

Keep reading

Concept art · pre‑alpha