The World Vol 4 · The Terrarium
ch 42 / 105
Chapter 42

Run It Until It Dies

The 200-year run

Six years leaves the terrarium looking alive and proves almost nothing. Trees have barely spent their ground, scrub has not fed a second generation on top of the first, and no lineage has grown old. Take the stop out, run 200 years unpaced, print one census per midsummer, and do not tune the model when the census collapses; the collapse is the measurement.

The run needs two more pieces before it can stand on its own. Founding plants must come from a seeded stream instead of a hand-picked list, and old plants must be able to die even when they do not starve in the current tick.

Those two pieces claim streams 10 and 11. Stream 10 governs plant mortality. Stream 11 places the founding generation. The row order fixes which plant spends which draw.

The census tape

A census is three numbers per row per year: how many of that kind are standing, the grams they hold between them, and the grams the average one is holding. The third is the first two divided, and it earns its column. A count and a total can both sit still while the valley moves underneath them; thirty plants at forty grams and thirty plants at four hundred are the same two numbers and two completely different valleys. Every table below prints all three, and by the middle of the run the mean is the only one of them still saying anything.

▣ Build · stage 1 — the census, and a third way to stop standing
// internal/terra/valley.go

// Roll is one row's line in a census: how many of that kind are
// standing, the grams they hold between them, and the grams the
// average one is holding. The third number is the first two divided,
// and it is in here rather than left to the caller because a count on
// its own and a mass on its own can both hold still while the valley
// changes underneath them.
type Roll struct {
	N    int
	Mass float64
}

// Mean is the grams one plant of this row is holding, or nothing at all
// when none of them are standing.
func (r Roll) Mean() float64 {
	if r.N == 0 {
		return 0
	}
	return r.Mass / float64(r.N)
}

// Take is the census: one Roll per row of the species table, counted in
// the order the stands are held so two runs of one seed add the same
// numbers in the same sequence.
func (v *Valley) Take() []Roll {
	out := make([]Roll, len(Flora))
	for _, st := range v.Stands {
		k := v.rowOf(st)
		out[k].N++
		out[k].Mass += st.Plant.Mass
	}
	return out
}

The death sweep at the end of a tick already knew two ways to finish a plant. It now knows three, and it writes down which one it used, because a valley where everything starves and a valley where everything grows old are two different accounts of the same falling count.

	live := v.Stands[:0]
	for _, st := range v.Stands {
		up, _ := st.Kind.Awake(v.Climate, theta)
		how := -1
		switch {
		case st.Plant.Mass < st.Kind.Least:
			how = Starved
		case st.Kind.Annual && !up:
			how = Ended
		case v.Wear > 0 && st.Kind.Span > 0 &&
			v.luck.Float64() < v.Wear*st.Kind.Hazard():
			how = Unlucky
		}
		if how < 0 {
			live = append(live, st)
			continue
		}
		v.Gone[v.rowOf(st)][how]++
		v.Bed.Fall(st.At, Pile{Mass: st.Plant.Mass, Nutrient: st.Holds()})
		v.Fell += st.Holds()
	}
	v.Stands = live

Span is a new field on the species row, in years: twelve for the moss, sixty for the scrub, three hundred for the tree, and nothing at all for the annual, which has a shorter way of dying already. Hazard turns it into a chance per tick, one over the ticks in the span, and Wear on the valley multiplies it. The six-year bench left Wear at zero and drew no numbers at all off stream 10, which is why its output has not moved a bit; a run this long cannot leave it there.

▣ Build · stage 2 — a founding generation on stream 11
// Found scatters a founding generation over the valley: n seedlings of
// every row, on soil cells drawn from stream 11, refusing a cell that
// already has something on it and refusing to plant anything on rock or
// in the pond. It is the one place in this world where a plant appears
// somewhere nothing put it, and a run founded this way does not depend
// on which handful of cells somebody liked the look of. The rows are
// walked in table order, so who gets first pick of the ground is fixed
// and every seed of the draw is spent even when a cell says no.
func (v *Valley) Found(n int) int {
	var soil []sim.Coord
	for y := 0; y < v.Grid.H; y++ {
		for x := 0; x < v.Grid.W; x++ {
			c := sim.Coord{X: x, Y: y}
			if v.Bed.Rootable(c) {
				soil = append(soil, c)
			}
		}
	}
	if len(soil) == 0 {
		return 0
	}
	made := 0
	for k := range Flora {
		for i := 0; i < n; i++ {
			c := soil[v.where.IntN(len(soil))]
			if v.Taken(c) {
				continue
			}
			v.Plant(k, c)
			made++
		}
	}
	return made
}

Three of every row is twelve draws, and a draw that lands on a taken cell is spent without planting anything, so the founding is twelve plants at most and often fewer. Saying so out of the return value costs one integer and buys a line in the header that no reader has to take on trust.

The loop itself has nothing new in it whatsoever. That is the point of the chapter.

▣ Build · stage 3 — the tick loop with nothing waiting on the clock
// cmd/ages/main.go

	wall := time.Now()
	log := make([]year, 0, years)
	for y := 1; y <= years; y++ {
		for {
			v.Tick()
			if v.Now%terra.Year == terra.Quarter+1 {
				break
			}
		}
		log = append(log, snap(v, y))
	}
	spent := time.Since(wall)
$ go run ./cmd/ages -mode pace
ages: what two hundred years costs, at the rate volume 1 fixed

  ticks in a year                        3600
  years                                   200
  ticks in the run                     720000
  ticks a second, paced                    10
  paced, that is                      20h0m0s

  a census at every midsummer is 200 lines; every tick is 720000

Volume 1's runner takes a Paced flag and, when it is set, waits on a ticker before every step so that ten ticks of the world cost one second of yours. That is the right rate for a world somebody is looking at. Here it would cost twenty hours to find out one thing, and the census would print one line every six minutes for all of them. Nothing in the simulation cares. A tick is a function call; the ticker is a thing bolted on outside it, and taking it off is a change to the caller and not to the world.

∑ Interlude — sim time against wall time

Numbers first. A year in this valley is 3,600 ticks, so two hundred years is 200 × 3,600 = 720,000 ticks. At volume 1's ten ticks a second that is 720,000 ÷ 10 = 72,000 seconds, and 72,000 seconds is twenty hours. The same 720,000 ticks with the ticker taken out came back in 8.296 seconds on the machine this was written on, which is 86,792 ticks a second: 8,679 times faster than the clock would have permitted.

Write the ticks in a year Y, the years y, the ticks in the run T, the rate in ticks a second r, and the wall-clock cost W in seconds. Two multiplications and a division:

T = y · Y and W = T ÷ r

Both rates go in the same slot. Paced, r is a number you chose and W is what it costs you; unpaced, r is a number the machine hands back and W is what it managed. The second r moves with the hardware, so it carries the same warning every measured figure in this book carries: yours will differ, and the arithmetic around it will not.

The last number is what the method costs. Two hundred censuses out of 720,000 ticks is one reading every 3,600, which is 0.028 per cent of the run. Everything that happens between two midsummers happens where nobody is looking, and the run below is going to make you pay for exactly one of those blind spots.

Yticks in one of this valley's years: 3,600
yyears the run covers
Tticks in the whole run, y times Y
rticks a second: chosen when paced, measured when not
Wwall-clock seconds the run costs, T divided by r

Years 1 to 12

Start short, because the first dozen years hold everything the next hundred and eighty-eight only finish. Twelve years is 43,200 ticks, and about a second and a half on the machine this was written on.

▣ Build · stage 4 — twelve years, one census each
$ go run ./cmd/ages -mode run -years 12 -every 1
ages: 12x8 valley from seed 5, 44 soil cells, 12.00 light on an average day
      founded in mid spring with 3 of every row on stream 11, 12 took a cell
      12 years, 43200 ticks, no pacing, one census at every midsummer
      the air holds 3960 seeds: 44 soil cells times the 90 of the biggest clutch

   year              moss              herb             scrub              tree   standing
           n    mass  mean    n    mass  mean    n    mass  mean    n    mass  mean      grams
      1    3    93.9  31.3    3    63.1  21.0    3   493.1 164.4    3   867.4 289.1     1517.5
      2    0     0.0   0.0    0     0.0   0.0   18  1263.6  70.2    4  1144.8 286.2     2408.4
      3    0     0.0   0.0    0     0.0   0.0   29  1412.2  48.7    6  1291.2 215.2     2703.3
      4    0     0.0   0.0    0     0.0   0.0   32  1399.2  43.7    6  1164.8 194.1     2563.9
      5    0     0.0   0.0    0     0.0   0.0   32  1352.2  42.3    6  1086.2 181.0     2438.3
      6    0     0.0   0.0    0     0.0   0.0   34  1321.8  38.9    6  1030.6 171.8     2352.5
      7    0     0.0   0.0    0     0.0   0.0   36  1289.5  35.8    4   965.3 241.3     2254.9
      8    0     0.0   0.0    0     0.0   0.0   41  1787.4  43.6    3   623.7 207.9     2411.1
      9    0     0.0   0.0    0     0.0   0.0   39  1700.8  43.6    3   559.5 186.5     2260.3
     10    0     0.0   0.0    0     0.0   0.0   39  1622.6  41.6    3   503.5 167.8     2126.1
     11    0     0.0   0.0    0     0.0   0.0   37  1528.1  41.3    3   483.4 161.1     2011.5
     12    0     0.0   0.0    0     0.0   0.0   39  1457.9  37.4    3   462.2 154.1     1920.0

The moss and the herb are gone by the second census and never come back. Between them they released 41 seeds in the whole two centuries, against the scrub's 29,528, and the two of them lost the valley in the first twelve months of it. Both reasons were already on the table: the herb wants nearly fourteen per cent of an average day's light before it will start at all, and the moss stands seven hundredths of a cell tall and drops most of its clutch on the cell it grew on. What the census adds is that the argument was settled inside one year.

Now read the scrub's three columns across, and read them in the right order. The count climbs the whole way: 3, 18, 29, 32, 32, 34, 36, 41. The total climbs to 1412.2 by year 3 and then goes flat, wandering between 1289 and 1787 for the next nine years. The mean does neither. It falls off a cliff: 164.4, then 70.2, then 48.7, and it is under forty by year twelve. The valley is filling up with scrubs and each new one is smaller than the last, and only one of the three columns is saying so.

The tree column is the same argument run slowly. Three trees at the founding, four by year 2, six from year 3 to year 6, and for a while their mean holds up better than the scrub's: 289.1 grams each, then 286.2, then 215.2. Then the count starts falling and the mean never recovers. By year 20 there are three trees left carrying 48.5 grams apiece, a twelfth of what one tree reaches standing alone on open ground, and the same weight as the scrubs underneath them. The tallest row in the table, the one that takes the light before anything else gets a look at it, has been brought down to the size of its own understorey.

▣ Build · stage 5 — the same twelve years, from underneath
$ go run ./cmd/ages -mode run -years 12 -every 1   (second table of the same run)
  what the valley is holding, and what has stopped standing since it opened
   year   in soil  in litter  in tissue   in bank    starved  year ended    unlucky
      1   137.400    214.533    176.067     0.000          0           0          0
      2    89.079    181.558    247.533     7.730          3           3          0
      3    14.267    205.470    278.404    23.320          6           3          0
      4    26.489    193.106    258.665    39.420         18           3          0
      5    37.714    183.182    244.055    48.800         31           3          0
      6    50.524    176.280    233.906    48.900         45           3          1
      7    64.974    168.263    222.173    49.820         61           3          2
      8    80.151    164.495    200.804    54.260         76           3          3
      9    95.924    153.254    185.972    57.600         99           3          4
     10   111.679    143.301    172.880    59.430        120           3          4
     11   126.645    135.851    164.194    55.560        144           3          6
     12   140.092    129.621    156.797    50.850        165           3          7

This valley opened holding 528 nutrient units, twelve in each of its 44 cells of soil, and nothing puts any more in: the seeding chapter closed with the observation that seeds are the first thing in this world able to carry matter over the rim, and nothing at all carries any back. By the first midsummer 137.4 of those units are still in the ground. By the third there are 14.267, which is under three per cent of the stock. The rest is standing up as tissue or lying on the cells as litter.

Then the soil column turns round and climbs, every year, for the rest of the run. That is the part to hold on to. The starved column climbs with it, from 6 to 165 in nine years, and by the twelfth year the ground has 140 units back and 165 plants have died of not being able to pay their bills.

2703.3 grams down to 1.8

Eight and a bit seconds for the whole two centuries, so run it and read the census as it comes.

▣ Build · stage 6 — two hundred years, a census every ten
$ go run ./cmd/ages -mode run -years 200
   year              moss              herb             scrub              tree   standing
           n    mass  mean    n    mass  mean    n    mass  mean    n    mass  mean      grams
      1    3    93.9  31.3    3    63.1  21.0    3   493.1 164.4    3   867.4 289.1     1517.5
      2    0     0.0   0.0    0     0.0   0.0   18  1263.6  70.2    4  1144.8 286.2     2408.4
      3    0     0.0   0.0    0     0.0   0.0   29  1412.2  48.7    6  1291.2 215.2     2703.3
     10    0     0.0   0.0    0     0.0   0.0   39  1622.6  41.6    3   503.5 167.8     2126.1
     20    0     0.0   0.0    0     0.0   0.0   31  1305.4  42.1    3   145.4  48.5     1450.8
     30    0     0.0   0.0    0     0.0   0.0   21   704.4  33.5    2   138.4  69.2      842.8
     40    0     0.0   0.0    0     0.0   0.0   17   508.8  29.9    2    47.1  23.5      555.9
     50    0     0.0   0.0    0     0.0   0.0   14   312.1  22.3    1    27.7  27.7      339.8
     60    0     0.0   0.0    0     0.0   0.0    9   201.5  22.4    1    12.3  12.3      213.7
     70    0     0.0   0.0    0     0.0   0.0    7   126.4  18.1    1     6.5   6.5      132.9
     80    0     0.0   0.0    0     0.0   0.0    8    84.2  10.5    1     1.0   1.0       85.2
     90    0     0.0   0.0    0     0.0   0.0    6    50.0   8.3    0     0.0   0.0       50.0
    100    0     0.0   0.0    0     0.0   0.0    2    29.3  14.6    0     0.0   0.0       29.3
    110    0     0.0   0.0    0     0.0   0.0    2    17.4   8.7    0     0.0   0.0       17.4
    120    0     0.0   0.0    0     0.0   0.0    1    11.4  11.4    0     0.0   0.0       11.4
    130    0     0.0   0.0    0     0.0   0.0    1     7.9   7.9    0     0.0   0.0        7.9
    140    0     0.0   0.0    0     0.0   0.0    1     4.6   4.6    0     0.0   0.0        4.6
    150    0     0.0   0.0    0     0.0   0.0    1     3.1   3.1    0     0.0   0.0        3.1
    160    0     0.0   0.0    0     0.0   0.0    1     1.8   1.8    0     0.0   0.0        1.8
    170    0     0.0   0.0    0     0.0   0.0    1     1.8   1.8    0     0.0   0.0        1.8
    180    0     0.0   0.0    0     0.0   0.0    1     1.8   1.8    0     0.0   0.0        1.8
    190    0     0.0   0.0    0     0.0   0.0    1     1.8   1.8    0     0.0   0.0        1.8
    200    0     0.0   0.0    0     0.0   0.0    1     1.8   1.8    0     0.0   0.0        1.8

Read the last column down and there is no argument left to have. The valley carries 2703.3 grams of living tissue at its best, in year 3. A hundred and eighty-eight years later it carries 1.8. That is one plant, a scrub, weighing less than four seeds. Nothing else is standing anywhere on the map. The tree column runs out at year 90; the last tree in this world was alive in year 86.

There is no rally in it. From year 3 the standing column falls in every single one of the printed rows, and it falls smoothly: roughly halving every fifteen years for the first century, then more slowly, and then arriving somewhere it cannot leave. The last five printed rows all read 1.8. A run that swung up and then down would be telling you about a control problem; this one is not swinging.

Two named patterns are in that column and they should be kept apart, because they have different causes and only one of them is about crowding.

The first is competitive exclusion, and it happens twice here at two speeds. Four rows started. Inside one year two of them were gone, and neither was eaten or pushed off a cell by force: they were out-earned on the same ground by rows that could hold the same light for a smaller bill. The slow version took the tree, over eighty-six years. That is what a limiting resource does when more than one kind is spending it, and no line of code anywhere implements it.

The second is boom and bust. The scrub went from 3 plants to 41 in eight years and from 41 back to 1 in the hundred and ninety-two after that, and the valley's standing mass went 1517.5, then 2703.3, then 1.8. A population that overshoots its ground and settles back below the peak is an ordinary thing. This one does not settle anywhere: the ending is roughly a fifteen-hundredth of the peak, and about a hundredth of what one scrub weighs standing alone on open ground.

The two together produce an ending no one would have designed. The scrub won every argument it had, and what it won was a valley it cannot live in.

▣ Build · stage 7 — the ground, the register, and the books
$ go run ./cmd/ages -mode run -years 200 -every 50   (the tables after the census)
  what the valley is holding, and what has stopped standing since it opened
   year   in soil  in litter  in tissue   in bank    starved  year ended    unlucky
      1   137.400    214.533    176.067     0.000          0           0          0
      2    89.079    181.558    247.533     7.730          3           3          0
      3    14.267    205.470    278.404    23.320          6           3          0
     50   342.920     20.987     22.883     6.990        989           3         24
    100   373.715      1.719      1.756     0.570       1458           3         24
    150   376.192      0.182      0.186     0.000       1470           3         26
    200   376.281      0.108      0.111     0.000       1470           3         26

  every row, over the whole run
            peak n in year peak mass   in year last seen  released      grew
  moss           3       1      93.9         1         1        18         7
  herb           3       1      63.1         1         1        23         0
  scrub         41       8    1787.4         8  standing     29528      1461
  tree           6       3    1291.2         3        86       578        20

             starved  year ended    unlucky       all
  moss            10           0          0        10
  herb             0           3          0         3
  scrub         1440           0         23      1463
  tree            20           0          3        23

  no slot in the air: 0, and the fullest the air ever got was 1256 of 3960

  the books in grams              the books in nutrient units
    standing            1.8439      in living tissue     0.110634
    in the air          0.0000      in the air           0.000000
    in the bank         0.0000      in the bank          0.000000
    lying dead          0.0000      lying dead           0.108274
    burned         842106.0410      in the soil        376.281092
    rotted          14283.2020      blown away         151.500000
    blown away       2231.0000      the valley opened  528.000000
    ever built     858622.0869      difference           0.000000
    difference          0.0000

  world 493261435901c120 after 720000 ticks
  720000 ticks in 8.476s, 84943 ticks a second (measured here; yours will differ)
  the same run paced at 10 ticks a second would take 20h0m0s

Fourteen hundred and ninety-nine plants have died in this valley and 1,470 of them starved. Twenty-six ran out of luck, three were annuals reaching the end of their year, and that is the entire register. Nothing was eaten, nothing burned, and nothing was pushed off a cell by force. Every plant that fell in two hundred years fell because it could not cover its own upkeep.

And the ground they starved on is holding 376.281 of the 528 units the valley opened with. Not fourteen, the way it stood in year 3. Three hundred and seventy-six, more than two thirds of everything there ever was, sitting in the soil at the end of a run whose entire death register reads starved. Both differences at the bottom are zero to every digit printed, so this is not an accounting leak: the grams add up, the nutrient units add up, and the valley really is that full and that empty at the same time.

One more figure before the diagnosis is handed over. The stock does not come back to 528, and the missing 151.5 units are in the column marked blown away. Over two centuries this valley put 2,231 grams of seed over its own rim, and every gram of that took its nutrient with it. Nearly twenty-nine per cent of everything the world opened with left on the wind, and it is not coming back, because there is no mechanism in this world that brings any.

One number from the row table explains why the run has no ending except this one. The scrub released 29,528 seeds over two centuries and 1,461 of them ever stood up, which is one in twenty. That rate was survivable while the plants making the seeds were large, and it stopped being survivable when they were not. The last plant on the map settles the question for good: a scrub has to be standing at two grams before a quarter of itself pays for one whole seed, and the one alive in year 200 weighs 1.8439. This valley now holds no seed in the air, none in the ground, and one plant that will never make another.

Two columns of the census over two hundred years Two stacked plots sharing a year axis from 1 to 200. The upper plot is grams of living tissue, scaled 0 to 2800. It climbs steeply from about 1500 in year 1 to a peak of 2703 in year 3, wobbles for a few years around 2400, and then falls away in a long smooth curve that is almost at the bottom of the plot by year 100 and flat on it from year 120 onward, ending at 1.8. The lower plot is nutrient units in the soil, scaled 0 to 528, with a dashed line across the top marking the 528 the valley opened with. It falls from 137 in year 1 to its lowest point of 14 in year 3, exactly where the tissue plot peaks, then rises steadily for the rest of the run and levels off at 376. The two curves are mirror images: the ground empties as the plants fill it and refills as they die, and neither returns to where it started. TWO HUNDRED YEARS, IN TWO COLUMNS OF THE CENSUS GRAMS OF LIVING TISSUE 2800 1400 0 year 3: 2703 grams, the most it ever holds year 200: 1.8 grams, one plant NUTRIENT UNITS IN THE SOIL 528 264 0 528: what the valley opened with year 3: 14 units left in the ground year 200: 376 1 50 100 150 200 year
Figure 42.1 — the two curves are each other upside down, and they turn on the same year. The gap between the dashed 528 and where the lower curve settles is 151.7 units: the 151.5 this valley blew over its own rim as seed, and the last quarter of a unit still held in one plant and one pile of litter.

Four seed histories

One run is one run. The terrain, the wind field, the founding draw and every dispersal in two hundred years all come off a single number, so change that number and everything changes with it. If the collapse is a property of the model it will survive that; if it is a property of seed 5 it will not.

▣ Build · stage 8 — four worlds, the same two hundred years
$ go run ./cmd/ages -mode seeds
ages: the same 200 years under several world seeds, 3 of every row founded

   seed  cells   peak grams  in year   most scrub  in year   at the end      grams   in soil   blown out
      3     42       2419.1        3           39        7   scrub tree        3.7     360.7       142.7
      5     44       2703.3        3           41        8   scrub             1.8     376.3       151.5
      7     54       3150.8        3           44        6   tree             55.9     463.9       169.3
     11     51       3328.0        2           37        6   scrub            13.9     441.4       168.7

Four terrains between 42 and 54 cells of soil, four peaks between 2419 and 3328 grams, and every one of those peaks in year 2 or year 3. Every valley then spends the rest of its two centuries coming down, and every one of them ends under 56 grams with between 360 and 464 nutrient units still lying in the ground. The moss and the herb are extinct in all four. The winner is not always the same: seed 7 finishes with five trees and no scrub at all. Which row survives is a detail of the draw. That one does, and that it survives on crumbs, is not.

Numbers are the argument and the client is the reason to believe it. The painter that drew seeds falling in the last chapter moved into a package of its own the moment a second bench wanted it, and it draws this valley the same way it drew that one.

▣ Build · stage 9 — the valley founded, full, and finished
$ go run ./cmd/ages -mode frame -at 1,8,200 -strip assets/frames/valley-two-centuries.png
  year 1, tick 901, summer, daylight 1.6000, 12 standing at 1517.5 grams
  moss 3 herb 3 scrub 3 tree 3, 0 waiting in the ground, soil nutrient 137.400
    ############
    #.t..ms.h.s#
    #.....t..m.#
    #.~~~~~....#
    #.~~~~~~h..#
    #...~~~~...#
    #...~m..sht#
    ############
  frame 68333ff00c5710feb22269d1db2c47c98f1e5c3001e927566d1fae7b81bcdbc1

  year 8, tick 26101, summer, daylight 1.6000, 44 standing at 2411.1 grams
  moss 0 herb 0 scrub 41 tree 3, 1513 waiting in the ground, soil nutrient 80.151
    ############
    #stssssssss#
    #ssssssssss#
    #t~~~~~ssss#
    #s~~~~~~sss#
    #sss~~~~sss#
    #sss~ssssst#
    ############
  frame 278f2f763f5882e8d2e9a184a4faa4d35b1ad43b09ba446e1de0c825657de4b0

  year 200, tick 717301, summer, daylight 1.6000, 1 standing at 1.8 grams
  moss 0 herb 0 scrub 1 tree 0, 0 waiting in the ground, soil nutrient 376.281
    ############
    #......s...#
    #..........#
    #.~~~~~....#
    #.~~~~~~...#
    #...~~~~...#
    #...~......#
    ############
  frame 297926c080668e242aee8b7fc1960767a2755afe3d04768484c3155a9760ae04

  the 3 frames side by side, 1184 by 256: 17c4d59dd0588f0f49ec969204cc4f33b1cc7118d9d9b54216a03e3d64727ac8
  wrote assets/frames/valley-two-centuries.png

Count the letters in the year 8 map. There are 44 of them and this valley has 44 cells of soil, so every cell of ground a root can live in has a plant standing on it, and 1,513 more seeds are lying in the ground waiting for one of them to move. That is the fullest this world will ever be, and it happens in the eighth year of a two-hundred year run. The year 200 map has one letter on it.

Three top-down valleys side by side on a grey background, each brown soil with a blue pond, 192 by 128 pixels doubled. The first has a dozen small green plants scattered thinly across it with wide bare gaps. The second is covered: green stalks stand on every patch of soil, evenly spaced, right up to the water's edge, and a few are noticeably taller than the rest. The third is bare brown soil and blue water with a single faint green mark near the top edge.
Figure 42.2assets/frames/valley-two-centuries.png: the valley in year 1, year 8 and year 200, drawn by the same painter at the same scale. The middle one is 44 plants on 44 cells of soil. The right-hand one is 1.8 grams.
⚠ Worked failure — a pool sized from a column that is always zero

The air needs a pool, and the pool needs a size. Chapter 41's valley bench printed a flying column in its census, and here is every value that column took in six years: 0, 0, 0, 0, 0, 0. Not one seed was ever in the air when the census was taken. So a few hundred slots would obviously do, and the run below asks for 400.

$ go run ./cmd/ages -mode run -years 200 -air 400 -every 200
      the air holds 400 seeds, set on the command line

   year              moss              herb             scrub              tree   standing
           n    mass  mean    n    mass  mean    n    mass  mean    n    mass  mean      grams
    200    0     0.0   0.0    0     0.0   0.0    1     2.0   2.0    0     0.0   0.0        2.0

  no slot in the air: 13767, and the fullest the air ever got was 400 of 400
  world dca4c16062c015ff after 720000 ticks

The census is entirely plausible. One scrub, two grams, everything else gone, the same ending as the honest run to within a fifth of a gram. Nothing in it looks wrong, no error is printed, and both ledgers still close at zero, because a seed that never got into the air was counted where it fell instead. If the seed ledger had not carried a no slot column, this run would have been publishable and false.

13,767 seeds never left their parent. The high-water mark of the honest run says the air held 1,256 at its fullest, so 400 was short by a factor of three, and the world digest says the two runs are not the same world after tick one of the first crowded autumn.

Trace the mistake back and it is not about pools at all. Every row in this table seeds on the tick its own window shuts, which falls in autumn for all four of them, and a seed is in the air for anything from one tick to a few dozen. The census is taken at midsummer. The flying column was therefore structurally zero: not a measurement of a quantity that happened to be small, but a reading taken at the one time of year when it is guaranteed to be nothing. A number sampled once a period tells you nothing about a quantity whose whole life is shorter than the period. The right size came from arithmetic instead: 44 cells, the largest clutch any row in the table can pay for is 90 seeds, so 3,960 is the worst the air can ever be asked to hold, and the program prints that sum in its own header.

The negative result

The method under this page is older than simulation and it has three moves. Build the instrument before the run, so what gets recorded is not chosen by what you hoped to see. Record every period and pick the interesting ones out afterwards: the peak year in the run above was found by scanning a column for its largest number, and if the peak had fallen in year 90 the same three lines of code would have printed year 90. Then keep a ledger that has to close, so that a collapse can be told apart from a leak in your own bookkeeping.

That third one is what makes this a finding rather than a bug report. A world losing plants could be a world with a subtraction in the wrong place. Here the grams balance to four decimals and the nutrient units balance to six, across 720,000 ticks, 858,622 grams ever manufactured and 30,000-odd seeds. Every gram is standing, lying dead, burned as upkeep, rotted, or gone over the rim, and the same is true of every nutrient unit. Nothing here went missing. It was all spent, and the books say on what.

The census earns its third column here too. If it printed only counts, the run from year 3 to year 12 reads as a healthy population climbing from 29 to 39. If it printed only totals, the same years read as a plateau. The mean is the column that says the newcomers are arriving smaller and smaller, and it starts saying so in the second year of the run, six years before the count peaks and turns. Choosing what to record is most of the skill in this kind of work, and the cost of one extra division per row per year was nothing at all.

Accelerated time bought the finding and it charged for it. Twenty hours of paced world became eight seconds, and in exchange nobody watched a single tick of it. Everything in the run above was learned from 200 readings out of 720,000 ticks, and the one thing that was hidden by that sampling rate cost a worked failure to find. Both halves of that trade are permanent: any run fast enough to answer a question about centuries is too fast to watch, and every quantity in it that lives and dies between two readings is invisible by construction.

◆ Note — what this run is not evidence of

It is Be careful about how far four seeds reach. The runs above say that this valley, at this calibration, on these four terrains, collapses. They do not say that unmanaged ecologies must collapse, and they do not say that any particular number in the species table is wrong. A different soil stock, a different rain, a bigger map or a fifth row could all move the ending, and none of that has been tested here.

What has been established is narrower and enough to work with: the collapse is not one unlucky draw, it is not an accounting error, and it is not caused by anything the simulation does randomly. That is the ground the next two chapters stand on, and it took a run long enough to be embarrassing to get it.

✓ Checkpoint — what two centuries said
  • Given a tick count and a tick rate, you can work out what a run costs paced and what it cost unpaced, and say which of the two figures moves when the hardware changes.
  • Reading a census, you can say what the count, the total and the mean each know that the other two do not, and point at the year in the run above where they first disagree.
  • state the three ways a plant stops standing in this world, read the register at the end of the run, and say which of them accounted for 1,470 of 1,499 deaths.
  • name the two places two hundred years of this valley's nutrient ended up, give the figure for each, and say which of the two can never come back.
  • Shown a long run whose ledgers close and whose population is gone, you can argue that the collapse is in the model rather than in the bookkeeping, and say what you checked.
  • Handed a quantity that is sampled once a year, you can work out whether its lifetime is shorter than the sampling period before you trust a single reading of it.
⚡ Exercises — try first, then reveal
Exercise 1 — accuse the wrong suspect. Twenty-six plants ran out of luck in that run, and mortality was the mechanism this page added. Predict what happens with it switched off, then run go run ./cmd/ages -mode run -years 200 -wear 0.

The peak comes out identical to the digit: 29 scrubs and 6 trees in year 3, 2703.3 grams, because no plant in the first three years was old enough for the hazard to have caught it. The ending moves from one scrub at 1.8 grams to three scrubs at 5.8, which is 5.8 grams against 2703.3 instead of 1.8 against 2703.3. And 1,256 plants still starve.

So the answer is that the mechanism this page added is not the one doing the killing. It moved the ending from 1.8 grams to 5.8 and left the whole first act alone, and a run with no luck in it anywhere still empties out. When something collapses shortly after you add a feature, turning the feature off is the cheapest experiment available, and it is do it before any theory gets written down.

Exercise 2 — start with more. Predict what founding the valley with ten of every row instead of three does to the peak and to the ending, then check with go run ./cmd/ages -mode run -years 200 -found 10.

The peak arrives a year earlier and is bigger: 2952.2 grams in year 2 against 2703.3 in year 3. The ending is one scrub at 9.4 grams. More founders means the ground is stripped sooner, which is the same run with the first act played faster, and 1,742 plants starve instead of 1,470.

The useful thing here is what does not change. If the ending depended on the founding population, more founders would buy something real; what they buy is a peak one year sooner, 249 more grams at the top of it, and 9.4 grams standing at the end instead of 1.8. Whatever is driving this is not the number of plants you begin with.

Exercise 3 — take away half the sky. The species chapter worked out what halving the daylight does to every row's ceiling. Predict what it does to two hundred years, then run go run ./cmd/ages -mode run -years 200 -light 6.

The peak drops to 2274.2 grams and moves out to year 5: less light means slower growth, so the ground takes longer to empty and the top of the curve is lower and later. Two hundred years in, the valley holds one scrub and one tree between them weighing 10.4 grams, and that tree is the one genuine surprise on offer: it is still standing in the dim run, where in the bright one the last tree had been gone for over a century. It cost more trees to get there, 91 dead against 23.

One column changes character. In the bright run, not one seed in two centuries was ever refused a cell for want of light; in this one, 423 were. Halving the sky finally made light a binding constraint on germination, and it still did not change the ending.

So: 1,470 plants starved to death on ground holding two thirds of the nutrient the world was founded with, and the valley reached the fullest it would ever be in its eighth year of two hundred. Nothing in that is random, nothing in it is an accounting error, and nothing in it depends on the seed. It is arithmetic, and arithmetic can be drawn: every quantity in this valley feeds something that feeds it back, and the next thing to do is put those loops on paper and find the one with nothing at all pushing the other way.