FIELD NOTES — TERRAIN
Rivers that know where they are going
Our first rivers hung in mid-air over trenches they never filled. How the world generator decides where water goes, and what put the rivers back in their beds.
Until September 11, the rivers in Orebound were hovering. The world generator found each one, dug it a channel twelve meters wide and six deep, and then drew the water at the height the ground had been before the digging. From a distance: a river. From the bank: a thin sheet of water stretched across the top of an empty trench, like laundry on a line.
Putting them back in their beds took one day, two versions of the world generator, one idea we threw away and one that was, quite literally, average.
Where the water goes
The rivers know where they are going long before there is any water to draw. The generator works on a height grid of 2,113 by 2,113 samples, one per meter. Once the noise has made hills, about 1.1 million simulated raindrops roll down them, picking up soil where they speed up and dropping it where they slow. That carves gullies, and the rivers will follow them later.
Then comes the hydrology. Starting from the sea and the map edge, a priority flood works inland, always continuing from the lowest cell it has reached so far. Any cell lower than the one that reached it is raised to that level, plus a sliver. When it is done, every hollow on the map is filled to the point where it would spill over, and every cell has a downhill path to the sea or the edge. Hollows filled by more than 1.4 meters become lakes.
The sliver gives a filled lake a slope of a few millimeters per cell, enough for water to find its way across to the outlet. When drawing, we flatten each lake to its spill level. Lakes are tilted for the hydrology and level for your eyes.
Next, each cell points at its lowest neighbor out of eight: its downstream. We go through the cells from highest to lowest, and each hands its running total to its downstream neighbor. What arrives is a cell's flow, the number of cells that drain through it. At the default settings a cell becomes river once about 27,500 square meters of hillside drain through it.
So every river cell has a pointer to the next one, all the way to a lake or the sea. The trouble was everything after that.
Floating, and hollow
Once the rivers are found, the generator carves them in. Around every river cell it lowers the ground with a soft cosine bell: full depth at the center, fading to nothing six cells out. The water surface, however, was still set on the river cells alone, at the height of the original ground. The channel and the water had each been built correctly. Neither had been told about the other.
We measured it on our reference map. There were 10,064 places where river water met dry ground. At 1,039 of them the water stood more than half a meter above the ground beside it; at the worst, 5.8 meters.
The new erosion had flushed out a second bug that morning. The check "is this river cell next to the open sea?" used heights after carving, so a channel cut below sea level passed for ocean, and one lake's outlet was handed sea-level water six meters below the lake. It now uses the heights the hydrology saw, before any carving.
Filling the channel
The repair has three parts.
First, a river surface now sits below its banks, not level with them. A fill setting of 0.6 puts it 40% of the carve depth below the original ground at the centerline. That level is spread over every cell the carving touched, and a cell is wet only where the level is above the carved ground. The banks rise through the water and the shoreline lands where they cross it: on flat ground, about seven meters of water in a twelve-meter channel. Every wet cell is also relabeled as river, so the riverbed coloring and the swim surface match the water you see. If it looks like water, you can swim in it, and the other way round.
Second, backwater. A river's surface may never sit below whatever it flows into. applyBackwater walks each river from its mouth upstream and raises any cell that sits lower than its downstream neighbor, or lower than the lake or sea it ends in. Without it, a river dipped two or three meters below its lake just before arriving, and the blend near the mouth drew the water climbing uphill into the lake.
Third, the mouth blend now also covers the channel's dry banks, so water lifted toward a lake can spread over them instead of standing above ground nobody checked.
Mismatches over half a meter fell from 1,039 to 61, and the worst from 5.8 meters to 1.5, at a junction where one river joins another.
Nearest wins, and loses
The first version of that spread was the obvious one: each channel cell copies the level of the nearest river cell. On a straight stretch that works. At a bend, or where two rivers meet, two cells side by side can have nearest sources several cells apart along the flow, at different heights. The result was steps of a meter or more in the water surface. Waterfalls nobody had designed.
The replacement takes a weighted average of every river cell within reach, using the same cosine bell that carves the channel. An average changes smoothly as you move, so the seams went away. On a straight stretch with an even fall it changes nothing, since the average of a straight line is the line itself. There is a test for that, because it is exactly the kind of property that quietly stops being true.
Steps of more than a meter between neighboring water cells went from 135 to 5, and the worst from 2.69 meters to 1.05. In the same run, shoreline mismatches dropped from 63 to 41, the worst from 1.5 meters to 0.73.
We also tried a second rule on top: a cap on how far the surface could rise from one cell to the next going upstream. Measured against the average alone, it did no better, so we took it out. A rule that doesn't move the numbers is still something somebody has to read.
Deep enough, and no deeper
Later that afternoon the world got taller. We raised the vertical scale from 120 to 350, and mountain peaks went from about 58 meters to about 127. Carve depth is a fraction of that scale, so the trenches grew with it, to 17.5 meters under every river cell, hillside trickle and main river alike. Lake basins bottom out about 12 meters below the surface and stay shallow near the shore. Rivers now met their lakes as gorges.
So depth now follows flow. Flow spans several orders of magnitude, so we interpolate on a log scale: depth follows roughly how many digits the flow has, not the flow itself. The smallest river on the map cuts 30% of the maximum depth, the biggest cuts all of it, and the maximum came down to about 12 meters. A headwater now runs in a channel about 3.7 meters deep, its surface a meter and a half below the banks; the main river sits about five meters down. The blend at the mouth grew from 5 cells to 12, so a river eases into its lake rather than dropping in.
Six worlds in one day
The generator's output is pinned by checksums in our tests: change one river cell and the build fails until we declare, on purpose, that the world has changed by bumping the generator's version number. On Friday, September 11, it went from 11 to 17. Only two of those were rivers; the rest were landforms, taller relief and grass. It was a busy Friday.
Junctions are still where the water is least tidy. Otherwise the rivers in Orebound now run downhill, sit in their channels and reach the lake at the lake's own level. That shouldn't count as an achievement. It took a day anyway.