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

A Loop With No Brake

Starvation on a full account

The two-century run ends with 1,470 starvation deaths out of 1,499, while the bed still holds 376.281 of the 528 nutrient units it opened with. Both books replay and both close. Diagnose only the loops the code actually walks: draw each arrow from a measured transfer, write the quantity on it, and count which arrows push back against growth.

The valley starved on a full account because full is not the same as reachable. Nutrient can rot onto rock, settle under pond water, or leave over the rim in a seed. None of those places pays a root.

Randomness is not the suspect. The run with luck removed keeps the peak and still empties the standing crop. The failure is feedback: mass buys seed, seed buys neighbours, neighbours draw the bed down, and no term falls as crowding rises.

Loop gain

The instrument is a second command against the same module. It founds the valley cmd/ages founds, runs the ticks cmd/ages runs, and changes nothing at all about either. What it does differently is take its readings at both ends of a year and subtract, so that a line of its output is one turn of the circle instead of one snapshot of the valley.

▣ Build · stage 1 — one turn of the loop per line
// cmd/loops/main.go

// gain reads the reproduction loop one year at a time. A line is one
// turn of the loop: what was standing at a midsummer, what it put into
// the air the autumn after, and how many of those seeds were standing
// plants by the midsummer following. The last column is the gain.
func gain(seed uint64, light float64, years int) {
	v, g := open(seed, light)
	planted := v.Found(3)
	...
	midsummer(v)
	for y := 1; y <= years; y++ {
		roll := v.Take()[scrub]
		fuel := v.Bed.Held().Nutrient
		was := [2]int{v.Seed.Released[scrub], v.Seed.Fate[scrub][terra.Grew]}
		midsummer(v)
		sent := v.Seed.Released[scrub] - was[0]
		took := v.Seed.Fate[scrub][terra.Grew] - was[1]
		per := 0.0
		if roll.N > 0 {
			per = float64(took) / float64(roll.N)
		}
		fmt.Printf("  %5d %6d %9.1f %7.2f %10.3f %9d %8d %9.3f\n",
			y, roll.N, roll.Mass, roll.Mean(), fuel, sent, took, per)
	}
}
$ go run ./cmd/loops -mode gain -years 20
loops: one turn of the reproduction loop a line, seed 5, 44 soil cells
       founded with 3 of every row, 12 took a cell
       a line is what stood at one midsummer and what it left standing at the next

   year  scrub     grams    mean in the bed     seeds     took per plant
      1      3     493.1  164.35    137.400       184       15     5.000
      2     18    1263.6   70.20     89.079       701       13     0.722
      3     29    1412.2   48.70     14.267       796       12     0.414
      4     32    1399.2   43.72     26.489       836       11     0.344
      5     32    1352.2   42.26     37.714       805       14     0.438
      6     34    1321.8   38.88     50.524       946       16     0.471
      7     36    1289.5   35.82     64.974      1225       20     0.556
      8     41    1787.4   43.60     80.151      1256       22     0.537
      9     39    1700.8   43.61     95.924      1146       21     0.538
     10     39    1622.6   41.60    111.679      1017       24     0.615
     11     37    1528.1   41.30    126.645       945       24     0.649
     12     39    1457.9   37.38    140.092       892       25     0.641
     13     37    1387.2   37.49    152.035       831       26     0.703
     14     36    1344.2   37.34    164.080       796       26     0.722
     15     36    1302.2   36.17    175.161       757       27     0.750
     16     33    1267.5   38.41    185.556       773       28     0.848
     17     34    1420.1   41.77    195.044       749       25     0.735
     18     35    1380.2   39.44    204.242       717       24     0.686
     19     33    1334.5   40.44    214.156       681       23     0.697
     20     31    1305.4   42.11    223.455       653       22     0.710

The seeds column is the loop's output and it climbs for eight straight years: 184, 701, 796, 836, 805, 946, 1225, 1256. Nothing about the valley filling up made this population produce less. At the year the valley is at its fullest, with a plant standing on every one of its 44 cells of soil, it is putting more seed into the air than in any year before it.

Now look at the last column, because it is a trap and the trap is instructive. New plants per standing plant reads 5.000, then 0.722, then 0.414, and a number that falls that sharply looks exactly like a population discovering its own limit. It is not doing that. A new plant needs an empty cell, and by the second midsummer 18 of 44 cells are taken, so no matter how many hundreds of seeds come down that column cannot exceed 26 ÷ 18 = 1.444. By the third year the arithmetic ceiling on it is 15 ÷ 29 = 0.517. That column stopped measuring the plants some time in year two and started measuring the room left over.

∑ Interlude — gain, and what a loop with gain does

Numbers first. Three scrubs stood at the first midsummer. Fifteen new ones were standing at the second, so each of the three left five behind: call that five the gain of one turn. Push it forward with nothing pushing back. Three plants become 3 + 15 = 18, eighteen become 18 + 90 = 108, and a hundred and eight become 648. The valley has 44 cells. On this arithmetic the third year is when the plants run out of ground, and the third year is exactly where the run's soil column falls to 14.267 and the mean mass of a scrub has already dropped from 164.35 grams to 48.70.

Write the quantity going round the loop x, the number of turns n, and the gain g, which is what one turn multiplies x by. One turn is a multiplication, and n turns is that multiplication done n times:

x(n+1) = g · x(n) and so x(n) = x(0) · gⁿ

Three cases and no others. With g below 1 the quantity fades to nothing. With g at exactly 1 it holds still. With g above 1 it multiplies, and it keeps multiplying, and it does not slow down on its own at any value of x whatsoever, because g does not depend on x. Here g = 6: each plant is still there and has left five more. One more turn is 3,888, and there are 44 cells.

So a loop with gain above one always ends the same way, by running into something outside itself. The interesting question is never whether it stops. It is what stops it, and there are two very different answers to that, which the next section separates.

xthe quantity going round the loop: standing plants, here
nturns of the loop; one turn is one year in this valley
gthe gain: what one turn multiplies the quantity by
Nplants standing right now
Kcells of this valley a root can live in: 44

Neighbour cost

There is competition in this code and it is not imaginary. A crown writes shade into the light field before any plant reads out of it, and root discs overlap, so two plants close together share ground that one plant would have had alone. Both of those take something off a plant when a neighbour arrives. The question is how much, and the way to find out is to vary the crowding on purpose and hold everything else still.

▣ Build · stage 2 — the same ground, one to twenty-nine tenants
// crowd founds n scrubs and nothing else, and reads them at their first
// midsummer, before any of them has seeded. It is the density question
// asked directly: what does one more neighbour cost a plant, and what
// does the whole standing crop have to spend on seed once it has paid
// for them.
func crowd(seed uint64, light float64) {
	for _, n := range []int{1, 2, 4, 8, 16, 32, 44} {
		v, _ := open(seed, light)
		took := v.FoundRow(scrub, n)
		midsummer(v)
		roll := v.Take()[scrub]
		var lit, offered float64
		clutch := 0
		for _, st := range v.Stands {
			lit += v.Sky.At(st.At)
			offered += v.Bed.Offer(st.At, st.Plant.Root, 0).Nutrient
			clutch += st.Kind.Clutch(st.Plant.Mass)
		}
		...
	}
}
$ go run ./cmd/loops -mode crowd
loops: n scrubs founded alone on the seed-5 valley and read at the
       first midsummer, with nothing else standing anywhere in it

   asked   took      grams     mean its light its ground      seeds
       1      1      214.9   214.87    14.294    180.707        107
       2      2      429.7   214.87    14.294    120.707        214
       4      4      859.5   214.87    14.294    104.859        428
       8      8     1442.5   180.32    10.418     96.330        717
      16     14     2364.5   168.90     9.279     70.886       1175
      32     24     3421.5   148.76     7.376     39.090       1698
      44     29     3845.4   137.33     6.478     26.962       1909

The first three rows are identical to the last digit printed. One scrub, two scrubs and four scrubs each hold 214.87 grams, because at those densities the crowns do not meet and the plants are light-limited anyway, so the shared soil never becomes the binding constraint. The first three neighbours are free. From eight tenants on, the coupling is real and it grows: 180.32 grams each, then 168.90, then 148.76, then 137.33.

So there is a negative term in this model. Now price it. Going from one plant to twenty-nine multiplies the tenants by 29 and the mass of each by 137.33 ÷ 214.87 = 0.639. The standing crop is those two multiplied together, 29 × 0.639 = 18.5 times what one plant held, and the seed the crop pays for goes 107 → 1909, a factor of 17.8. Crowding the valley twenty-nine-fold made it produce almost eighteen times the seed.

That comparison is the whole test, and it makes a rule. For crowding to hold a population steady, the mass of one plant has to fall at least as fast as the number of plants rises: double the tenants and each one must end with half as much, so the crop and its seed stay put. Here twenty-nine times the tenants cost each of them 36 per cent. In the language of the interlude, the gain of this loop is still far above one at every density the valley can hold, and it stays above one right up to the last free cell.

Which leaves the difference the chapter turns on. Something that lowers the rate at which a loop feeds itself is a brake: the loop slows as the quantity grows, and it settles at whatever level makes the gain exactly one. Something that removes units of the quantity from outside the loop is a wall: the loop goes on demanding growth at full strength, and the only reason the number stops rising is that the surplus is being killed. Braked systems settle. Walled systems pile up against the wall and die there. This valley has two walls, 44 cells and starvation, and no brake at all, and the register at the end of the run is the receipt: 1,470 starved of 1,499.

Stranded nutrient

A loop that only ever pushes one way still cannot manufacture matter. Everything the plants are made of came out of 528 nutrient units, and every gram of tissue that dies is supposed to rot back into the ground the next generation spends. That returning arrow is the reason a valley can go round this loop more than once, so the next thing to measure is how much has actually travelled along each arrow.

▣ Build · stage 3 — every arrow, totalled over two centuries
$ go run ./cmd/loops -mode arrows
loops: every arrow in the loop, and what ran along it in 200 years

  grams
    light fixed into new tissue            858610.8
    tissue burned to pay upkeep            842106.0
    tissue spent on seed                    15947.5
    seed carried over the rim                2231.0
    dead tissue rotted away                 14283.2
    still standing                              1.8

  nutrient units
    the valley opened with                  528.000
    went from a body into a pile          60608.719
    rotted out of a pile into a cell      60608.611
    carried over the rim in seed            151.500
    held in living tissue now                 0.111
    lying in litter now                       0.108

  seeds released 30147, seedlings that took 1488, one in 20.3

The recycling arrow carried 60,608.719 units, and the valley only ever owned 528 of them. Divide: 60,608.719 ÷ 528 = 114.8. Everything in this world went round the circle about a hundred and fifteen times over. That number reframes the leak the seeding chapter warned about. The 151.500 units that blew over the rim are 28.7 per cent of the whole stock, which sounds like a catastrophe, but spread across a hundred and fifteen turns it is a quarter of one per cent per turn. A leak that small is invisible in any run short enough to watch, and on a loop that turns this often it is fatal.

One in 20.3 seeds became a plant. The other nineteen went somewhere, and each of them was carrying nutrient when it got there.

⚠ Worked failure — a diagram that proved the valley must recover

With the arrows totalled, the loop went on paper, and the paper made a prediction. Draw it: soil pays income, income builds mass, mass makes seed, seed makes plants, plants die, litter rots, and the nutrient goes back into the soil to be spent again. One arrow leaves that circle, the seed that clears the rim, and it carried 151.500 units. So the valley keeps 528 − 151.5 = 376.5, which is 71.3 per cent of its founding stock, and the census agrees to three decimals: 376.281 in the bed at year 200. A valley with 71 per cent of its nutrient should carry roughly 71 per cent of the 1517.5 grams it opened with. Call it eleven hundred grams, standing, for ever.

The run ends with 1.8 grams. The prediction is wrong by a factor of six hundred, and it is wrong in the direction that matters, so the diagram has an arrow in it that the code does not have. The suspect arrow is the return: litter to soil, drawn as though every pile of litter feeds every root. Testing it needed a total the bed had never been asked for.

// Rooted is what the bed holds in the cells a root can live in. It is
// not the same number as Held: litter falls wherever a seed does, bare
// rock and open water included, and the nutrient that rots out of it
// goes into the cell it was lying on whether or not anything can ever
// put a root there. A plant can only spend this one.
func (b *Bed) Rooted() Cell {
	var t Cell
	for y := 0; y < b.H; y++ {
		for x := 0; x < b.W; x++ {
			c := sim.Coord{X: x, Y: y}
			if !b.Rootable(c) {
				continue
			}
			s := b.cells[b.index(c)]
			t.Moisture += s.Moisture
			t.Nutrient += s.Nutrient
		}
	}
	return t
}
$ go run ./cmd/loops -mode ground
loops: the column the census calls "in soil", asked which cells it is in

   year   in the bed a root reaches  under rock  under water
      1      137.400       137.400       0.000        0.000
      3       14.267         1.769       8.508        3.989
     10      111.679         1.234      66.587       43.858
     50      342.920         0.181     210.920      131.820
    100      373.715         0.015     230.480      143.220
    200      376.281         0.001     232.310      143.970

  44 cells of soil, 36 of rock, 16 of open water

  where the 30147 seeds of this run ended, and the nutrient each
  parcel of them was carrying when it got there
    germinated                 1488       49.900
    blown off the valley       4168      151.500
    landed on rock             6550      232.310
    landed in the pond         4125      143.970
    aged out of the bank      13816      486.340

  the one plant left standing, at 7,1, holding 1.8439 grams
    its roots reach 15 cells and they offer it 0.001092 nutrient units
    light on its cell 19.158, water under it 18.110, so the limit is nutrient
    it can fix 0.0182 energy a tick and its upkeep is 0.0148
    the least mass that pays for one seed of its row is 2.00 grams

The reachable ground holds 0.001 units. Not 376. The whole 376.281 is sitting on the 36 cells of bare rock and under the 16 cells of open water, where 10,675 seeds landed over two centuries and rotted, and the arithmetic closes exactly: 232.310 on the rock plus 143.970 in the pond is 376.280 of the 376.281 the bed is holding. Add the 151.500 that left over the rim and 527.780 of the valley's 528 units are somewhere no root will ever reach them again.

The mechanism is two loops in the code that walk different sets of cells and were drawn as one arrow. Bed.Rot sweeps every pile of litter on the grid and puts what it burns into the cell underneath, rock and water included, because a pile that is nowhere would be a hole in the books. Bed.Roots filters a disc down to cells that are soil. So the arrow into the ground covers 96 cells and the arrow out of it covers 44, and nothing anywhere moves a nutrient unit sideways between them. Bed.Regen exists and Valley.Tick never calls it; the tick runs the shower, the evaporation and the rot, and nothing in it carries a nutrient unit from one cell to another.

The last plant is the whole diagnosis in one readout. Its cell is in full daylight at 19.158 and standing over 18.110 units of water, and it is limited by nutrient, on 0.001092 units, at the centre of a valley whose books say it is two-thirds full. It fixes 0.0182 energy a tick against an upkeep of 0.0148, so it grows by a rounding error and sits at 1.8439 grams, and its row needs 2.00 grams to pay for a single seed. It cannot starve and it cannot breed. A total is not a supply. Adding a quantity across cells that cannot trade with each other invents an average nothing can spend.

The loop as the code draws it, and where the seeds put the nutrient Two stacked panels. The upper panel is a ring of four boxes joined by arrows going clockwise: nutrient in reach feeds income each tick, income each tick feeds grams standing, grams standing feeds seeds and then plants, and seeds and then plants feeds back into nutrient in reach. Every arrow means more of this gives more of that, and nothing on the ring falls as the neighbours multiply. The lower panel shows the 30,147 seeds of the run splitting four ways, with the count and the nutrient units each parcel carried: 1,488 germinated carrying 49.9 units and back in play, 4,168 blown over the rim carrying 151.5 units and gone, 10,675 onto rock or into the pond carrying 376.3 units and stuck out of reach, and 13,816 aged out in the ground carrying 486.3 units and back in play. The two rows marked in red never return, and together they are 527.8 of the 528 units the valley opened with. THE LOOP AS THE CODE ACTUALLY DRAWS IT NUTRIENT IN REACH 137.400 down to 0.001 INCOME EACH TICK the least of three GRAMS STANDING 2703.3 at the peak SEEDS, THEN PLANTS 30147 in two centuries roots draw, crown fixes caught, minus upkeep a quarter of the mass one seed in twenty takes EVERY ARROW ON THIS RING READS MORE OF THIS, MORE OF THAT nothing anywhere on it falls as the neighbours multiply WHERE THOSE SEEDS PUT THE VALLEY'S NUTRIENT SEEDS RELEASED 30147 WHERE THEY ENDED SEEDS UNITS germinated 1488 49.900 in play blown over the rim 4168 151.500 gone rock and the pond 10675 376.280 stuck aged in the ground 13816 486.340 in play no way back the two marked rows never come back, and together they are 527.780 of the 528 nutrient units the valley opened with
Figure 43.1 — the ring at the top has four arrows and every one of them carries the same sign, so there is nothing on it for a growing population to run into. The lower panel is the arrow the first diagram left out: a seed that never becomes a plant is still carrying nutrient when it lands, and the two rows marked in red take a little over half of it somewhere the ring can never draw on again.

The density brake calculation

Control theory has one idea at its centre and this is the place to meet it. If you want a quantity to sit at a value instead of running away from it, you measure the quantity and feed the measurement back into the thing that drives it, with the sign reversed, so that more of the quantity means less driving. A thermostat is that sentence in a box: the warmer the room reads, the less the heater runs. The loop is still a loop, and it still has gain, but the gain now falls as the quantity rises, so there is exactly one level where it equals one and the system walks to it and stays.

For a valley, the quantity to measure is the crowding and the thing to drive is growth. Give a plant a coefficient it multiplies its income by, and let that coefficient fall as the count of standing plants rises toward the number of cells the valley has. Write it c = 1 − N/K: at one plant on 44 cells the coefficient is 0.977 and almost nothing changes, at 22 plants it is one half, and at 44 it is zero and nothing grows at all. None of that is written yet. It can still be costed, because the numbers it would multiply have all been measured.

▣ Build · stage 4 — the prediction, costed before it is built
// brake works the arithmetic of a growth coefficient that falls as the
// neighbours crowd in, and then asks what that coefficient does to the
// two arrows that leave. Nothing here changes a valley: the coefficient
// is multiplied into numbers already measured, and every line below is
// a prediction rather than a result.
func brake(seed uint64, light float64) {
	// M: one scrub with the ground to itself, at its first midsummer.
	lone, g := open(seed, light)
	lone.FoundRow(scrub, 1)
	midsummer(lone)
	m := lone.Take()[scrub].Mean()
	k := g.Count(sim.Soil)
	...
	for _, n := range []int{6, 11, 22, 29, 33, 41, 44} {
		c := 1 - float64(n)/float64(k)
		mean := c * m
		fmt.Printf("  %6d %13.3f %12.2f %14.1f %10d\n",
			n, c, mean, float64(n)*mean, n*row.Clutch(mean))
	}
}
$ go run ./cmd/loops -mode brake
loops: what a growth coefficient c = 1 - N/K would do, worked on paper
       against numbers already measured. No valley is run with it.

  K, the cells of this valley a root can live in            44
  M, one scrub's grams with the ground to itself        214.87

       N   c = 1 - N/K   mean grams standing grams      seeds
       6         0.864       185.57         1113.4        552
      11         0.750       161.15         1772.7        880
      22         0.500       107.44         2363.6       1166
      29         0.341        73.25         2124.3       1044
      33         0.250        53.72         1772.7        858
      41         0.068        14.65          600.7        287
      44         0.000         0.00            0.0          0

  the largest standing crop is at N = K/2 = 22, and it is K*M/4 = 2363.6 grams,
  holding 2363.6 x 0.06 = 141.8 of the valley's 528.0 nutrient units

  and what that crop does to the two arrows that leave:
    seeds it releases every autumn, for ever                  1166
    the share of a seed rain that strands, measured          0.492
    nutrient units one scrub seed carries                    0.030
    units leaving reach every year                           17.22
    years of that the valley's 528 units cover                30.7

  the run without a brake released 30147 seeds in two centuries,
  which is 151 a year, because a dying crop stops seeding

The top half is encouraging and the arithmetic behind it is useful. With the coefficient in, a plant's ceiling is c × M and the standing crop is N × c × M, which written out is N(1 − N/K)M. That expression is largest exactly halfway along, at N = K/2, where it comes to KM/4. Twenty-two plants, 107.44 grams each, 2363.6 grams standing. The run with no brake touched 2703.3 grams in year 3 and was past it in year 4. The braked figure is smaller, and the difference between them is that this one is a level and the other one was a peak.

The bottom half is the part to be honest about. A braked valley does not stop seeding: it holds 22 plants at 107 grams and releases 1,166 seeds every autumn for as long as it stands. The run that crashed averaged 151 a year, because a population that is dying is a population that has stopped reproducing. Nearly half of any seed rain in this valley strands, measured over the run that already happened, at 0.492. So a stable crop pushes 1166 × 0.492 × 0.030 = 17.22 nutrient units a year out of reach, and 528 ÷ 17.22 is 30.7 years. Under the other three world seeds the same arithmetic gives 30.9, 53.9 and 41.5.

On this evidence a brake on its own is not a cure, and would arrive at the same ending sooner. It fixes the runaway and it does nothing whatever about the two arrows that leave, and by holding the population up it makes those arrows carry more. That is a prediction, not a result, and it is a first-order one: it multiplies a coefficient into a static crop and assumes the stranding fraction of a braked seed rain matches the crashing one, which is the weakest link in it and easy to imagine going either way. It is written down here so it can be checked rather than remembered.

◆ Note — three repairs, and only one of them is a brake

A valley that stays green needs work on all three findings, and they are independent. The runaway wants the density coefficient above. The stranding wants some way for nutrient to move between cells, so that what rots on the rim or in the shallows can reach a root that needs it, the same kind of neighbour sweep the fire and water rules already use, which would close the return arrow the first diagram assumed. The leak over the rim wants a decision rather than a mechanism: a valley whose edges return their seed, or a trickle of nutrient arriving from outside, or an accepted slow bleed with the run length chosen honestly around it. Guessing which of the three matters most is cheap. Sweeping them is not, and it is the only way to find out.

Arrows and signs

The method under this page generalizes past valleys, and it runs in three passes. First establish the sign of every arrow: for each link, does more of the source mean more of the target or less of it. Signs are cheap, they can usually be read straight out of the code, and a loop whose arrows are all the same sign is a loop that has no brake in it, whatever the numbers turn out to be. That pass alone predicted the boom.

Then size the negative terms, because a brake with the right sign and the wrong magnitude buys nothing. Shade and shared roots are real negative terms in this model and they cost a plant 36 per cent of its mass across a twenty-nine-fold crowding, which was never going to hold a population that multiplies sixfold in a year. Sign told us the loop was positive; only the measurement told us how far from balance it was, and the measurement is the one that says whether a fix has to be a new mechanism or a tuned constant.

Then check the reach of every quantity you have been adding up. This is the pass that is easy to skip and it is the one that cost a wrong prediction here. The bed's total was a real number, correctly computed, closing to six decimals against a ledger that balances, and it answered a question nobody had asked: what is on the grid, when what was wanted was what a root can spend. Aggregates hide geometry by construction. Any time a total is summed over cells that cannot pass anything between them, the total is an accounting fact and not a resource, and the only way to tell the two apart is to sum it again over the cells that can.

The last thing this run is evidence for is smaller than it looks, and saying so is part of the finding. Four world seeds crashed the same way and all four ended with their nutrient stranded and leaked, so the finding is structural. It is not evidence that the species table is wrong, that the map is too small, or that any un-managed valley must die. It is evidence about these arrows, and every one of them was drawn by reading the code and then measuring what ran along it.

✓ Checkpoint — what the arrows said
  • Given a loop's gain for one turn, you can push it forward by hand, say which of the three cases it falls into, and work out the turn on which it runs out of room.
  • state what separates a brake from a wall, and point at the two walls this valley has and the receipt in its death register.
  • Shown a per-capita rate that falls as a population grows, you can work out whether it is falling because of the organisms or because of the space left, and compute the arithmetic ceiling that column is really tracking.
  • price a negative term by holding everything else still and varying the crowding on purpose, and say how fast the mass per plant would have to fall to hold a crop level.
  • Handed a total summed over a grid, you can ask which cells it is in and which of those cells the consumer can actually reach, and you can name the two methods in this module that walk different sets of cells.
  • multiply a proposed coefficient into measured numbers to cost a fix before writing it, and say which assumption in that costing is the one most likely to be wrong.
⚡ Exercises — try first, then reveal
Exercise 1 — dim the sky and re-price the neighbours. Less light means smaller plants, and smaller plants shade each other less. Predict what halving the daylight does to the crowding curve, then run go run ./cmd/loops -mode crowd -light 6.

One scrub alone comes out at 107.44 grams, exactly half of 214.87, because a plant on open ground here is light-limited and its ceiling is linear in the light. The interesting column is the last one. Twenty-nine tenants now hold 83.41 grams each against a lone plant's 107.44, a ratio of 0.776 where the bright valley gave 0.639, and the seed the crop pays for climbs 53 → 1153, a factor of 21.8 against 17.8.

So halving the sky made the loop less self-limiting, not more. Dimmer plants are shorter and narrower, their crowns overlap later, and the only negative term with any size in this model gets weaker. A change that makes every individual worse off can make the population's runaway worse at the same time, and nothing but measuring the crowding curve would have told you which way it went.

Exercise 2 — a valley with more soil and less water. Seed 7 has 54 cells of soil and only 6 of open water, against seed 5's 44 and 16. Predict whether it strands less of its nutrient, then run go run ./cmd/loops -mode ground -seed 7.

It strands more, not less: 379.600 units on rock and 84.270 in the water at year 200, against seed 5's 232.310 and 143.970. The pond is smaller so less goes into it, the rock catches the difference, and the reachable ground finishes at 0.055 units out of the 463.925 the bed is holding. A bigger, wetter-looking valley bought 0.054 units.

The ratio of rock to water changed which sink filled up and changed nothing about whether the sinks fill. That is what makes this structural: the seeds are aimed by a wind field at a map with edges, most of them miss, and there is no arrow back from wherever they land.

Exercise 3 — cost the brake on the other three worlds. The thirty-year figure came off one map. Predict whether it is a property of seed 5, then run go run ./cmd/loops -mode brake -seed 3 and the same for 7 and 11.

Seed 3 gives 30.9 years, seed 7 gives 53.9 and seed 11 gives 41.5. Seed 7 does best by a wide margin and the reason is in its own output: its stranding share is 0.280 against seed 5's 0.492, because it has the most soil and the least water, so more of its seed rain lands somewhere a root can get at it later.

None of the four reaches a century. The number moves with the terrain and the verdict does not, which is the answer you want from a sensitivity check: if the prediction had come out at 30 years on one map and 3,000 on another, the arithmetic would have been telling you it depends on something you had not measured yet.

The diagnosis is finished and nothing in the valley has been changed. There are three repairs on the table, one coefficient costed at 2363.6 grams held instead of 2703.3 grams passed through, and a prediction on record that the coefficient by itself buys about thirty years. All of that is argument. The way to settle it is to write the brake, sweep it across a band of values instead of trusting the one that looked right on paper, give the nutrient somewhere to travel, and then run a valley long enough that a wrong answer has time to show.