Filling a world that was mostly empty
A dead world has a trap built into it: emptiness is the whole point, but to a player, "empty" and "unfinished" look identical. The middle stretch of development was almost entirely about closing that gap — making a quiet, sparse map feel intentional rather than abandoned by its developer.
The problem, drawn out honestly
At one point the map had exactly three named places — a camp, a dead forest, an ashen waste — all hugging the left edge along a single path, while the entire east was a huge unnamed blank with a few objects scattered in it. To stop pretending that wasn't a problem, the world got its own technical map document: a grid laid over everything, every cell marked as filled, sparse, or empty. Seeing six empty cells in a table is a lot harder to ignore than a vague feeling that "the east is a bit bare." From then on, filling the world meant working the grid cell by cell.
Occupancy: one registry so nothing grows out of a rock
The first thing that broke when the world got busier was placement. Trees grew out of boulders; fallen logs landed on top of artifacts; every system avoided every other system with its own ad-hoc, slightly-wrong logic. The fix was a single shared occupancy registry: every fixed structure — ridges, the camp, the poles, the props — reserves a circular footprint before the scatter systems run, and the trees and rocks then ask "is this spot free?" before placing themselves. First to reserve wins; the order things are registered is the priority order.
The part I'm happiest with is that it verifies itself. Every time the world regenerates, it prints an audit to the console: either "OK, no overlaps" or a warning with the exact coordinate of the collision. A whole category of "why is that tree inside that rock" bugs just stopped happening, because the world now checks its own work on every run.
Clearings, burn scars, and the no-green rule
Some places need to be deliberately bare — a scorched patch shouldn't have grass sprouting through it. That's a "clearing": a circle where the scatter systems simply skip. Burn scars use it heavily — a burnt patch is the same scorched ground texture used under a wrecked car, plus charred logs and blackened bushes, with a clearing over it so nothing healthy intrudes.
Then there's the rule that governs every plant in the game: nothing is green. Across every palette and tint, the green channel is never the brightest — the moment a bush reads as green, it reads as alive, and the world stops being dead. Variety comes from neutral greys nudged toward dust, slate, faint violet or rust, never from a healthy hue. It sounds like a tiny constraint; it's actually the single most important art rule in the project.
Height in a top-down world
One stubborn problem: how do you show elevation from directly above? A lot was tried and thrown out — procedural trenches, pixel slopes, a painted cliff plate — and all of them read as a smudge or a rug rather than a drop, because shading alone doesn't say "height" from a top-down angle. The answer that stuck was to make ridges out of big stacked-sprite boulders, the same fake-3D trick from the trees. A wall of rounded boulders is the one thing that both reads as elevation and matches the game's camera. The failed experiments are still in the repo, parked, as a note to self not to try them again.
Doubling the world, and paying for it
Once placement was solid, the world was doubled on each axis — four times the area — through a single scale constant. The trick was multiplying only positions and the extent of zones, never the objects' own sizes, so the landmarks stayed exactly as big but ended up with far more space between them, and the ground-scatter systems filled the new room on their own.
Bigger world, bigger bill. A performance pass found the real cost: every frame was nudging the slices of every tree and rock in the world, on-screen or not — so cost grew with the size of the map. Adding view-culling (objects far off-screen stop recalculating) made a frame cost roughly only what's visible, regardless of how big the world gets. That's the foundation that makes expansion possible at all — and it set the long-term plan: grow the world as loadable chunks, one location at a time, rather than one ever-growing mega-map.
Next time: the world is full, but full isn't the same as alive. The small, strange set pieces that give a silent map a pulse.