Drawing a whole forest for almost nothing

← All field notes

For a long stretch, The Long Watch had a forest the player couldn’t see. The trees were alive in the simulation — growing, aging, dying — but on screen they were all the same little tuft on the ground. The world was forested in the model and a meadow to the eye. This is the rendering half: teaching the hillside to actually look like trees, and proving it costs almost nothing to draw.

The trap of one object per tree

The obvious way to draw a forest is the expensive one: treat every tree as its own thing. Build a little model for it, hand that to the graphics card, repeat a few hundred times a frame. It works, and it’s how a lot of worlds are drawn — but the cost scales with the head-count, and a forest is the kind of thing that wants to grow without the frame rate flinching every time it does.

So we don’t. The trick the whole pass turns on is to stop drawing trees one at a time. We bake a single tree shape once — a boxy trunk with a boxy crown, deliberately blocky to sit inside the game’s voxel look — and then hand the graphics card that one shape plus a long list of places to stamp it. Draw a copy here, and here, and here. A hundred trees become one instruction with a hundred positions attached, not a hundred separate jobs. The card is extraordinarily good at exactly that kind of repetition; the work is in describing the shape well, not in repeating it.

A forest isn’t hundreds of things to draw. It’s one thing to draw, drawn in hundreds of places.

One shape, every age

A baked shape sounds rigid — surely a seedling and a hundred-year oak can’t be the same model. They can, if the only thing that changes between them is size. Alongside each position in that long list, we carry one extra number per copy: how big this particular tree is. A seedling draws the shared shape at about a fifth scale, a sapling at about half, a full-grown tree at full size. Same baked geometry, three different stamps. No second model, no special case, no extra cost — the life stages a tree walks through over in-game decades are, to the renderer, just a multiplier riding along with the position.

That a tree even has those life stages — that the oak grows slowly and lives long enough to turn a field of grass into woodland — is its own story. Here it’s just the thing the one number has to cover.

Drawing a death

A forest isn’t only living trees, and the dead ones aren’t a single shape either. When a tree dies it doesn’t fall and vanish — it stands as a bare dead snag, then topples to a fallen log lying along the ground, then settles to a low scatter of litter before it’s finally gone. Each of those stages reads differently to the eye, so each gets its own baked shape and its own list of positions: the trunk standing, the trunk laid on its side and sunk a little into the soil, the flat scatter where the wood finally breaks down. And when a plant is wholly gone, the cheapest thing of all happens — it simply isn’t drawn.

Those dead stages, and what they mean — why a long-lived thing earns a long, slow leaving, and how the gift to the soil rises as the wood comes apart — are told elsewhere. That piece ends on an honest admission: the afterlife was real in the simulation long before it was drawn properly, so a dead oak wore the same stand-in shape its living form did. This is the pass that finally drew it — that gave the snag, the log, and the litter the readable silhouettes they’d been promised.

Building the lists in one walk

The whole forest, then, comes down to a handful of these stamped lists: one for the meadow grass, one for living trees, and a few for the dead forms. The work each frame is just sorting every plant into the right list — this one’s a living sapling, that one’s a fallen log, this one’s gone — and then handing the lists over. We do that in a single pass over the world’s plants: walk them once, drop each into its bucket, fill the buckets, draw. No re-scanning the population per category, no per-tree decision-making on the graphics card. The grass, which already drew this way, kept rendering exactly as it had — byte-for-byte unchanged.

There’s a heavier, more specialized machinery you can reach for when you need to draw vast numbers of something — a million blades, a forest that fills a horizon. We deliberately didn’t. At equilibrium the world holds only a few hundred living trees standing at once; it’s a sparse forest, not a dense one. The simpler batched approach is more than enough at that scale, and reaching for the heavy version would have been complexity bought against a problem we don’t have. The right tool was the smaller one.

The measurement

The reason all of this is worth telling is the number it landed on. We measured the new rendering at the production load — redrawing the entire forest at once: every tree at every age, plus the snags, the logs, the litter, and the whole meadow of grass underneath them — and the whole thing costs roughly three hundredths of a millisecond a frame. About a thirtieth of a millisecond, against a frame budget of around sixteen. Well under one percent of the time a single frame has to spend. To the budget, drawing the forest barely registers as happening at all.

That it landed so cleanly wasn’t luck — the room was already there. An earlier pass had gone hunting for the real cost in these scenes, found it wasn’t the drawing at all but a quieter piece of bookkeeping in the simulation, and bought back a chunk of the frame on purpose, precisely to leave headroom for richness still to come. That investigation is a story of its own; what matters here is that when the world finally filled in with visible trees, the new drawing cost dropped straight into the room that pass had set aside — with plenty to spare.


A view, never a hand on the world

One discipline made the whole pass safe to ship without a second thought: the rendering only ever reads the world. It looks at where each plant is, how old it is, whether it’s living or a snag or a log, and it draws what it sees — but it never writes a thing back. Nothing about how the forest grows, dies, or feeds the soil can change because we changed how it’s drawn, because the drawing is downstream of all of it and one-directional. The world evolves; the renderer watches and paints.

That isn’t just a comfortable belief — the simulation is built to replay byte-for-byte identically from the same seed, so we could check it cold: the same world, before and after the rendering work, came out bit-for-bit the same. (The machinery that makes that comparison trustworthy is a longer tale.) The forest learned to look like a forest, and the forest itself didn’t move.

This was the moment the world stopped being a field of identical tufts and read, plainly, as trees — living ones at every age, dead ones in every stage of their long leaving, on a hillside that holds a smooth sixty-frame calm at full load. We got the forest. And because the headroom was already banked and the drawing asks for almost none of it, we got to keep it smooth.

Keep reading

Concept art · pre‑alpha