The World Vol 5 · Bodies and Brains
ch 55 / 105
Chapter 55

The Loop Closes

The score-to-action contract

The hand-written rule has been the only thing turning sensor rows into actions. The network now has the matching ends: twenty-four inputs from the senses, six outputs for the table, and 378 weights drawn from their own stream.

The six outputs are scores against the six entries of the action table, taken in table order, and the creature does the highest-scoring action the check allows. No score means anything on its own; the order of the six is the contract between arithmetic and world.

The two sides fit because their sizes were fixed earlier. The sensor row is nine rays at two numbers each, four gradient numbers and two body readings. The table has six entries. The hidden row's twelve neurons are the only chosen size in the middle.

The hard part is where the scores meet legality. A network knows nothing about water, plants or the store. The valley knows nothing about weights. This page puts the meeting at the driver: rank the scores, ask the table's check in that order, and take the first action still legal on this tick.

The Wits value

Start with the type that holds both halves. It is a Mind, so the phase can hand it a row and take back an action without knowing what is inside it, and it carries three things besides the network itself.

▣ Build · stage 1 — a brain with a body attached to it
// internal/beast/wits.go

// Wits is a network wired into a creature at both ends. The sensor row
// goes in as the network's inputs, the numbers it hands back are read
// as one score for each entry of the action table, and the action taken
// is the highest-scoring one the check allows.
type Wits struct {
	Net  mind.Net
	Self *Beast
	Here *View

	// Blunt is the wiring as it was first written: the top score handed
	// straight to the tick with nothing asked about whether it is
	// allowed. It is kept behind a flag so the failure can be run
	// instead of described, and it is false in every creature this book
	// ships.
	Blunt bool

	Runs   int       // forward passes this brain has actually spent
	Held   int       // ticks it was not asked, because an action was under way
	Struck int       // scores the check has crossed out, added up over the run
	Wanted [Acts]int // what the top score asked for, whether or not it happened
	Took   [Acts]int // what the creature was left holding

	hid, out []float64
}

// NewWits wires one network to one creature and hands the creature back
// its own driver, so the two halves of the link are made in one place
// and cannot disagree.
func NewWits(n mind.Net, b *Beast) *Wits {
	if n.In != Inputs || n.Out != Acts {
		panic(fmt.Sprintf(
			"a %d-%d-%d network cannot drive a creature: the sensor row is %d numbers and the action table is %d entries",
			n.In, n.Hid, n.Out, Inputs, Acts))
	}
	w := &Wits{Net: n, Self: b}
	w.hid, w.out = n.Buffers()
	b.Mind = w
	return w
}

Self is the creature this brain answers for. A Mind is handed twenty-four numbers and nothing else, on purpose, and the check is a question about a body standing somewhere and not a question about a row. The body has to arrive from somewhere, and it arrives here, fixed once when the two are wired together and never looked up again. Here is the world as the phase opened, and the next section is about how it gets there. hid and out are this brain's own scratch, made once, so no two creatures ever write into the same slice and a tick of three thousand of them allocates nothing.

The two sizes are checked and not trusted, because getting either of them wrong is silent in the worst way. A network with twenty-three inputs reads twenty-three of the twenty-four numbers and answers confidently on the ones it read. A network with five outputs produces five scores for a six-entry table, and the entry left without a score is a thing no creature built that way will ever do in the whole history of the world. Neither mistake produces an error, a wrong answer, or a slow tick. Both produce a valley that is quietly less than it was meant to be, forever.

The bench prints both ends and the arithmetic between them, with no valley anywhere near it. Every figure on this table is a constant of the world.

$ go run ./cmd/wired -mode wire
wired: the sensor row is 24 numbers and the action table is 6 entries,
  so the network between them is 24-12-6 and owns 378 weights

    slot   action      price    ticks   allowed when
       0     rest     0.0000        1   nothing
       1     walk     1.2150        1   the cell ahead is not open water
       2   sprint     4.8600        1   the cell ahead is not open water
       3     left     0.4050        1   nothing
       4    right     0.4050        1   nothing
       5     bite     0.1500        2   tissue standing inside Reach

  the row's own slots, for the ends that are not a ray:
    row[ 0]  ray 0 distance, 0 at the eye and 1 at the sight cap
    row[ 1]  ray 0 code, what that ray is worth to a browser
    row[18]  the moisture slope, going east
    row[19]  the moisture slope, going south
    row[20]  the standing-tissue slope, going east
    row[21]  the standing-tissue slope, going south
    row[22]  the store, as a share of full
    row[23]  the speed, as a share of top

  one creature deciding once: 360 multiplications, 378 additions, 12 tanh,
  then at most 6 calls to the check and no allocation at all

Slot 0 is rest and slot 5 is a bite, and the table is indexed by exactly those numbers. That is the whole of the output end of the wiring: output k of the network is Table[k], no lookup, no map, no names. It holds because the constant order in act.go was written down once and nothing else in this package is permitted to decide what a creature can do. If a seventh entry ever joins the table, every network in the valley becomes wrong on the same day, which is exactly the property you want from a number that load-bearing: the mistake is loud and total instead of quiet and partial.

Three hundred and sixty multiplications is what one creature thinks with. Set that beside the four hundred-odd samples a fan of nine rays walks, because the two costs are the same order and only one of them is the part people expect to be expensive.

The ranked legality check

There are three places the join could go, and they are not equally good.

The first is inside the network. Teach it what is legal by putting legality into the sensor row, or add a seventh output that means "and this one is allowed". Both are out. The row is twenty-four numbers and its order is canon for every controller in this volume, so it cannot grow a legality column without invalidating every brain ever drawn. And a network told in advance which options are open has been handed the answer to the only question anybody wanted it to work out.

The second is after the pick, in the tick. Take the highest score, hand it to Do, and let the check refuse it. This costs nothing to build, because Do already does exactly that: a refused action becomes a rest, and the refusal comes back to the caller as an error. Its price is that the network's second choice is thrown away unread. A creature standing at the pond's edge whose best number is "walk" rests, and rests, and rests, while five other numbers it produced sit there saying what it would rather do instead.

The third is between them, and it is the one this chapter builds. Six numbers put the whole table in an order, and an order carries more than a single answer does. Walk it from the top, put each entry to the check in turn, and the first one that comes back allowed is what happens. Nothing is thrown away that did not have to be, and the tick never has to refuse anything, because nothing illegal ever reaches it.

Which settles what the code does and reopens where it lives. Not in Do, which is handed one action and has no idea there were five others. Not in Pick either, at first glance, because Pick sees a row of numbers and the check needs a valley. So the ranking walk goes into the one type that can hold both: the brain, which already knows its creature, given a pointer to the world the phase is reading.

▣ Build · stage 2 — the ranking, walked down against the check
func (w *Wits) Pick(row *Senses) Act {
	b := w.Self
	if b.Owed > 0 {
		w.Held++
		return b.Busy
	}
	w.Net.Forward(row[:], w.hid, w.out)
	w.Runs++

	var struck [Acts]bool
	for n := range Acts {
		best := 0
		for i := range Acts {
			if struck[i] {
				continue
			}
			if struck[best] || w.out[i] > w.out[best] {
				best = i
			}
		}
		if n == 0 {
			w.Wanted[best]++
		}
		struck[best] = true

		a := Act(best)
		if w.Blunt || w.Here == nil || b.Legal(a, w.Here) == nil {
			w.Took[best]++
			w.Struck += n
			return a
		}
	}
	w.Took[Rest]++
	return Rest
}

The first four lines are the note the action chapter left. A creature part-way through an action it took earlier is not asked anything: the tick already belongs to that action, and Do would drop whatever came back. The forward pass is the most expensive thing a creature does, and spending one to produce a number nobody will read is waste in its plainest form. A bite occupies two ticks, so in a valley of biters this branch skips about a quarter of all creature-ticks, which the census below counts.

The ranking is walked without sorting and without allocating. Six entries make the naive version cheap: find the largest score not yet crossed out, try it, cross it out, repeat. Thirty-six comparisons in the worst case against a slice header and a sort, and struck is an array of six bools on the stack. The comparison is strict, so two scores equal to the last bit are settled by table order, and the same tie comes out the same way on every machine that runs it. That is a fact the digests depend on, not a matter of taste.

The loop always ends before it runs out of entries. Rest is priced at nothing, so the store gate cannot refuse it, and its permission test is the one that says yes to everything. A creature that may do nothing else may always do nothing, and the line after the loop has never executed.

Here still has to arrive. The phase opens by building one index of the valley by cell, so that nine rays from three thousand creatures do not walk the stand list every time; the same index answers everything the check wants to know. Handing it over is one function and one type assertion.

▣ Build · stage 3 — the same world to the eyes and to the judgement
// Watch hands one reading of the world to every network-driven creature
// on a list. It is the whole of the join: the phase gives a creature's
// eyes the world it opened on, and this gives the same world to the
// creature's judgement.
func Watch(herd []*Beast, v *View) {
	for _, b := range herd {
		if w, ok := b.Mind.(*Wits); ok {
			w.Here = v
		}
	}
}

// cmd/wired: wiring a roster into the valley's tick, with the join in it.
func hook(v *terra.Valley, r *beast.Roster, buried func(beast.Carcass), no func(error)) {
	phase := r.Hook(v, scale(v), buried, no)
	v.Phase = func() {
		beast.Watch(r.Live, beast.NewView(v, r.Live))
		phase()
	}
}

Anything on the roster driven by something else is left alone, so a valley holding hand-written rules and networks side by side needs one call and no branches. And a brain that has never been handed a view still works: Pick checks for the nil, takes the top score, and lets the tick refuse it. The wiring degrades to the second design instead of crashing, which is the correct behaviour for a seam somebody might use without reading this page.

There is a cost in those two lines and it should be said out loud. The index is built twice a tick: once here, and once inside the phase, over the same valley and the same roster. The two are identical and one of them is waste. It is the price of a seam that lets a Mind see its inputs and nothing else, and in a valley of nineteen creatures it is invisible. In a valley of three thousand it is a line on a profile with somebody's name on it.

Now put a creature somewhere awkward and open up a single tick. Cell 3,4 is on the western shore of the pond, facing east, with water in front of it and nothing standing anywhere near its mouth.

$ go run ./cmd/wired -mode score -at 3,4
wired: 12x8 valley, tick 901, year 1 summer, 12 plants standing at 1517.5 grams

  creature 1 on 3,4 facing 0 degrees, 400.0000 in the store,
  brain 0 off stream 14, 24-12-6, tanh through the middle row
  19 other creatures standing about on stream 12, which its rays can see

  the row it read, the entries that are not zero:
    row[ 0]   0.0625   ray 0, how far it went
    row[ 1]  -0.5000   ray 0, what it met
    row[ 2]   0.0625   ray 1, how far it went
    row[ 3]  -0.5000   ray 1, what it met
    row[ 4]   0.0625   ray 2, how far it went
    row[ 5]  -0.5000   ray 2, what it met
    row[ 6]   0.0625   ray 3, how far it went
    row[ 7]  -0.5000   ray 3, what it met
    row[ 8]   0.0417   ray 4, how far it went
    row[ 9]  -0.5000   ray 4, what it met
    row[10]   0.0625   ray 5, how far it went
    row[11]  -0.5000   ray 5, what it met
    row[12]   0.0625   ray 6, how far it went
    row[13]  -0.5000   ray 6, what it met
    row[14]   0.0625   ray 7, how far it went
    row[15]  -0.5000   ray 7, what it met
    row[16]   0.0625   ray 8, how far it went
    row[17]   0.2500   ray 8, what it met
    row[19]  -0.0341   the moisture slope, going south
    row[22]   1.0000   the store, as a share of full

  the six numbers that came back, in table order:
                rest      walk    sprint      left     right      bite
     score   -0.1918    0.4753   -0.0323   -0.0721   -0.0325    0.4652

   rank   action      score      check   why not
      1     walk     0.4753    refused   creature 1 at 4,4 cannot walk: the cell ahead is open water or off the grid
      2     bite     0.4652    refused   creature 1 at 3,4 cannot bite: no standing tissue inside reach
      3   sprint    -0.0323    refused   creature 1 at 4,4 cannot sprint: the cell ahead is open water or off the grid
      4    right    -0.0325    allowed
      5     left    -0.0721    allowed
      6     rest    -0.1918    allowed

  the creature does turn right: 3 scores crossed out above it

Eight of the nine rays come back at minus a half, which is the code for water, and none of the eight got further than a sixteenth of the sight range: the animal is looking straight into the pond from a few pixels off the edge. Ray 8, the last one round to the right, met one of the other eighteen creatures instead. Of the four gradient slots only one prints at all, at about a thirtieth, so the ground here holds close to the same water in every direction and the same standing tissue in every direction, that amount being none. The store is full, so slot 22 reads exactly one.

Then six numbers, and three of them are refused. Walk and sprint would put weight on 4,4, which is open water. The bite has nothing inside a reach of one cell. The creature turns right, on the fourth-ranked score of six, two ten-thousandths below the sprint it was not allowed to take. Under the second design it would have rested. Under this one it turns, which at least changes what its rays will see next tick.

∑ Math Interlude — six numbers that are only ever compared

Write the six down in table order, from the run above: rest at -0.1918, walk at 0.4753, sprint at -0.0323, turn left at -0.0721, turn right at -0.0325, and bite at 0.4652. Two questions get asked of that list, and both of them are comparisons.

The first is the plain one: which is biggest? Walk, at 0.4753, beating the bite by 0.0101. The second is the one the check forces: which is biggest among the ones allowed here? The allowed list on this tick is turn left, turn right and rest, and the biggest of those three is turn right at -0.0325.

Those two questions have different answers, and the difference is the whole design. Taking the biggest of six and then testing it gives you walk, which cannot happen, so the tick substitutes a rest and the creature does an action that scored last. Taking the biggest of the allowed three gives you turn right, which scored fourth. Fourth is worse than first and enormously better than sixth.

Now add ten to every one of the six. They become 9.8082, 10.4753, 9.9677, 9.9279, 9.9675 and 10.4652. Every gap between every pair is the number it was before, so both comparisons come out exactly where they came out before, and the creature does the same thing. That is the property the output layer was left bare for. A squash on the output row would spend twelve multiplications and a transcendental function per creature per tick buying a range nothing reads.

Athe six entries of the action table, numbered 0 to 5 in table order
s[a]the score the network gave entry a; s[1] is 0.4753 above
Lthe entries of A the check allows for this creature on this tick; three of the six above
cany one number added to all six scores at once; 10 above
biggest of Lthe entry in L whose s is largest, which is what the creature does

In those terms: adding c to every s[a] leaves the biggest of L exactly where it was, for any L; and the biggest of A is not the biggest of L unless the biggest of A happens to be in L. Both are dull sentences about lists of numbers, and both are load-bearing.

The second claim is arithmetic, so it does not need testing. The first one runs through a real network and a real check, so it can be. Adding ten to all six output biases adds exactly ten to all six scores, and the bench does it and asks the same tick again.

$ go run ./cmd/wired -mode score -at 3,4 -lift 10 | tail -12
                rest      walk    sprint      left     right      bite
     score    9.8082   10.4753    9.9677    9.9279    9.9675   10.4652

   rank   action      score      check   why not
      1     walk    10.4753    refused   creature 1 at 4,4 cannot walk: the cell ahead is open water or off the grid
      2     bite    10.4652    refused   creature 1 at 3,4 cannot bite: no standing tissue inside reach
      3   sprint     9.9677    refused   creature 1 at 4,4 cannot sprint: the cell ahead is open water or off the grid
      4    right     9.9675    allowed
      5     left     9.9279    allowed
      6     rest     9.8082    allowed

  the creature does turn right: 3 scores crossed out above it

Every score up by ten to the last printed digit, the ranking unmoved, the same action taken. Six numbers with an arbitrary offset in them still name one action, and that is the only thing being asked of them.

One creature's tick as a closed loop, and the ranking of six scores being walked down against the check The upper panel shows a loop running left to right along the top and back along the bottom. Along the top: the valley as the phase opened, then nine rays with two slopes and two body readings, then the row of twenty-four numbers, then a twenty-four by twelve by six forward pass, then six scores. A line drops from the six scores into a wide box saying the ranking is walked down and the check is asked at each step, and from there an arrow runs left to a box saying one action is applied, which feeds back up into the valley. A note beneath says the twenty-four numbers are the only thing that crosses into the network. The lower panel is the ranking at cell 3,4, six rows from highest score to lowest: walk at 0.4753 refused because the cell ahead is open water, bite at 0.4652 refused because nothing is standing inside reach, sprint at minus 0.0323 refused for the water again, turn right at minus 0.0325 allowed and taken, turn left at minus 0.0721 allowed, and rest at minus 0.1918 allowed. A line beneath says the creature takes the fourth-ranked score of six. ONE TICK, ALL THE WAY ROUND NINE RAYS, SLOPES, BODY THE ROW: 24 NUMBERS 24-12-6 FORWARD PASS SIX SCORES, TABLE ORDER WALK THE RANKING DOWN, ASK THE CHECK AT EACH STEP ONE ACTION, APPLIED the row is the only thing that crosses into the network, and one small number crosses back THE RANKING AT CELL 3,4, HIGHEST FIRST 1 walk 0.4753 refused: the cell ahead is open water 2 bite 0.4652 refused: nothing standing inside reach 3 sprint -0.0323 refused: the cell ahead is open water 4 turn right -0.0325 allowed, and taken 5 turn left 6 rest the top three name actions this ground will not carry, so the fourth is what happens
Figure 55.1 — the loop above and one turn of it below. The only thing that reaches the network is twenty-four scaled numbers, and the only thing that comes back is an index into a six-entry table. Everything the check knows about ground and plants stays on the outside of that boundary and is applied to the ranking, not to the row.

Twenty ticks of an untrained network

One tick proves the wiring holds. Twenty of them start to show what an untrained network is actually like to live next to. The bench stands the same creature on the same pond shore, holds the valley still so nothing grows back underneath it, and prints what the top score asked for beside what the creature was left holding.

$ go run ./cmd/wired -mode tape -at 3,4 -ticks 20
wired: 12x8 valley, tick 901, year 1 summer, 12 plants standing at 1517.5 grams

  creature 1 put on 3,4 facing 0 degrees, 400.0000 in the store
  driven by brain 0 off stream 14
  the valley is held still, so nothing grows back while the creature eats

   tick   cell  facing wanted     did           price     haul    grams      store
      1    3,4    30.0 bite       turn right   0.4050   0.0000   0.0000   399.4350
      2    3,4    60.0 bite       turn right   0.4050   0.0000   0.0000   398.8700
      3    3,4    90.0 bite       turn right   0.4050   0.0000   0.0000   398.3050
      4    3,4    90.0 bite       walk         0.0000   0.3037   0.0000   397.8413
      5    3,4    90.0 bite       walk         0.0000   1.2150   0.0000   396.4663
      6    3,5    90.0 bite       walk         0.0000   1.2150   0.0000   395.0913
      7    3,5    90.0 bite       walk         0.0000   1.2150   0.0000   393.7163
      8    3,5    90.0 bite       walk         0.0000   1.2150   0.0000   392.3413
      9    3,5    90.0 bite       walk         0.0000   1.2150   0.0000   390.9663
     10    3,5    90.0 bite       walk         0.0000   1.2150   0.0000   389.5913
     11    3,6    90.0 bite       walk         0.0000   1.2150   0.0000   388.2163
     12    3,6    90.0 bite       walk         0.0000   1.2150   0.0000   386.8413
     13    3,6    90.0 bite       walk         0.0000   1.2150   0.0000   385.4663
     14    3,6    90.0 bite       walk         0.0000   1.2150   0.0000   384.0913
     15    3,7    90.0 bite       walk         0.0000   1.2150   0.0000   382.7163
     16    3,7   120.0 bite       turn right   0.4050   0.3037   0.0000   381.8475
     17    3,7   150.0 bite       turn right   0.4050   0.0000   0.0000   381.2825
     18    3,7   150.0 bite       walk         0.0000   0.3037   0.0000   380.8188
     19    3,7   150.0 bite       walk         0.0000   1.2150   0.0000   379.4438
     20    3,7   150.0 bite       walk         0.0000   1.2150   0.0000   378.0688

  20 ticks: 15 walk, 5 turn right
  0.0000 grams eaten, 378.0688 left in the store, standing on 3,7 facing 150.0
  20 forward passes spent, 0 ticks held by an action already under way
  the check crossed out 25 scores over the run, and the tick refused 0

The wanted column says bite on every one of the twenty ticks. That is not a bug and it is not the network noticing food, since there is none within sight. It is a network whose weights were drawn once and never adjusted, being fed rows that barely move: the bite output happens to sit highest for almost anything this creature can see, so it asks for a bite while walking past a pond with nothing in its mouth's range at any point.

What the creature actually does is the check's answer, tick by tick. It turns right three times until it is facing south, walks the length of the pond's western shore, turns twice more at the bottom, and carries on. Twenty-five scores crossed out over twenty ticks: an average of better than one refusal per decision, all of them absorbed inside Pick. The last line is the one to hold onto. The tick refused nothing at all, because nothing illegal ever got as far as the tick.

⚠ Worked failure — the top score handed straight to the tick

The first version of this wiring did not walk a ranking. It took the largest of the six, handed it to Do, and let the existing check refuse it, on the reasoning that the refusal machinery was already built and already tested and there was no sense writing a second one. That version is still in the type behind a Blunt flag, so the failure can be run instead of described.

$ go run ./cmd/wired -mode tape -at 3,4 -ticks 20 -blunt | tail -12
     14    3,4     0.0 bite       rest         0.0000   0.0000   0.0000   397.7600
     15    3,4     0.0 bite       rest         0.0000   0.0000   0.0000   397.6000
     16    3,4     0.0 bite       rest         0.0000   0.0000   0.0000   397.4400
     17    3,4     0.0 bite       rest         0.0000   0.0000   0.0000   397.2800
     18    3,4     0.0 bite       rest         0.0000   0.0000   0.0000   397.1200
     19    3,4     0.0 bite       rest         0.0000   0.0000   0.0000   396.9600
     20    3,4     0.0 bite       rest         0.0000   0.0000   0.0000   396.8000

  20 ticks: 20 rest
  0.0000 grams eaten, 396.8000 left in the store, standing on 3,4 facing 0.0
  20 forward passes spent, 0 ticks held by an action already under way
  the check crossed out 0 scores over the run, and the tick refused 20

Twenty ticks, twenty rests, and the creature has not moved a pixel or turned a degree. The symptom looks like a dead network: same action forever, no response to anything. It is not, and the tape says so in the column beside it, because the wanted column is not constant for a network that is doing nothing. It is constant because the top score is a bite on every tick, and there is nothing to bite on this cell, so the check refuses it on every tick and Do writes a rest in its place. The network is producing six different numbers, five of them naming things the creature could actually have done, and the wiring is throwing all five away.

The reasoning from symptom to cause runs through the last line. The tick refused twenty of twenty. A refusal is not free information: it says the driver asked for something the world would not carry, and a driver that asks for the same impossible thing twenty times running is a driver whose second opinion nobody is collecting. Compare that line with the same run above, where the check crossed out twenty-five scores and the tick refused none, and the two designs separate cleanly. Both consult the check exactly as often. Only one of them does anything with the answer.

Nineteen brains in one valley

Now let a population loose. Nineteen creatures scattered over the valley on stream 12, each drawn its own three hundred and seventy-eight weights off stream 14 in roster order, each with a full store, the whole roster registered into the valley's tick, and two years of seasons run over the top of it. Nothing is trained, nothing is selected, nothing reproduces. This is what a drawn brain does with a body.

$ go run ./cmd/wired -mode herd -herd 24 -years 2
wired: 12x8 valley, tick 901, year 1 summer, 12 plants standing at 1517.5 grams

  19 creatures on stream 12, 400.0000 in every store, each driven by
  a brain of its own off stream 14, never trained
  the creature phase runs once a tick out of terra.Valley.Phase

    tick   season  alive      eaten    carcass   standing       litter
    1351   summer     15   211.0096   160.0000     278.02      89.0844
    2251   autumn     10   722.3810   360.0000     453.04       7.6326
    3151   winter      4  1019.1334   600.0000     101.60     168.6833
    4051   spring      2  1188.1334   680.0000    1522.51      48.8258
    4951   summer      2  1358.3834   680.0000     616.52       0.0372
    5851   autumn      2  1526.6334   680.0000    1466.18      30.4865
    6751   winter      2  1751.6334   680.0000    1064.60       5.9419
    7651   spring      2  1976.1334   680.0000    2554.88       1.2100

  19 creatures started, 17 struck off, 2 still walking after 6750 ticks

             wanted  handed on      share
    rest       8175      10756      42.0%
    walk       2511        927       3.6%
  sprint       2478        580       2.3%
    left       1523       2280       8.9%
   right       1818       3091      12.1%
    bite       9101       7972      31.1%

  wanted is the top score, handed on is what came back out of Pick
  25606 forward passes spent, 7971 ticks held by an action under way
  the check crossed out 6654 scores inside Pick over the run

  where they stopped, 17 of them:
    on open soil           10
    on the rocky rim        7
    first at tick 1044 on 9,5, last at tick 3400 on 11,5

  still walking, and what each of them lived on:
        id     cell  grams eaten        store cells a tick grams in reach
         1      3,0     824.5932     399.6900       0.0000       109.4227
        18      6,1     535.1945     399.5300       0.0000        69.0776

  the books in grams
    in                       46567.944597      founded, grown and stood up
    out                      46567.944597      standing, walking, flying, lying, spent
    difference                  -0.000000      -1.455e-11, which is the last bits of the adding
    17 creatures struck off at 40 grams a body is 680.000000 grams of carcass
    handed to terra.Bed.Fall                        680.000000 grams

Seventeen of nineteen are dead inside two years, and four of them are gone by the first census line, four hundred and fifty ticks in. That is the result, and the temptation is to read it as a broken network and go looking for the bug. It is not one, and the way to be sure is to ask what a correct wiring of an untrained network would look like if you saw it. Untrained means the weights are three hundred and seventy-eight numbers drawn out of a stream, arranged in no particular relation to anything about being alive. A creature driven by them should do something consistent, arbitrary, and unhelpful. It should not do something random, because the same row through the same weights gives the same answer twice; and it should not do something useful, because nothing has ever pushed those weights toward useful. Consistent and stupid is the correct output, and consistent and stupid is what the tape and the census both show.

The census is the clearest evidence the loop is closed and not idling. Look at wanted against handed on. The top score asked for a bite 9,101 times and a bite came out of Pick 7,972 times, so the two ends of that row are within an eighth of each other. Rest was wanted 8,175 times and handed on 10,756, picking up the surplus as the fallback at the bottom of every exhausted ranking. Walk was wanted 2,511 times and came out 927, which is what a valley with a pond through the middle of it and a rocky edge does to a creature that wants to go forwards. Six thousand six hundred and fifty-four scores were crossed out over twenty-five thousand decisions, a little over one struck score per four decisions, and every one of them is a creature whose second or third opinion got used instead of dropped.

Nobody drowned. Not one of the seventeen died in the water, because a step into open water is one of the three things the check refuses outright, and a creature whose brain wants to walk into the pond is turned away from it every tick until something else scores higher. Ten died on open soil and seven on the rocky rim, which is the valley's real trap for an animal with no reason to prefer one kind of ground to another: nothing has ever grown on the rim and nothing ever will, so a creature that wanders onto it is walking on a surface where its store can only go down.

The two survivors need close reading, because they are not a success. Both are standing exactly still at zero cells a tick. Both have practically full stores. Both have a large plant inside a reach of one cell, and between them they have eaten 1,360 grams of the 1,976 the whole population took off the valley. They are creatures whose drawn weights happen to put the bite output on top for almost every row, which parked them next to the first plant they touched and kept them there for six thousand ticks. The same disposition that killed the others by making them ask for a bite on bare soil kept these two alive by making them ask for a bite next to a tree. Nothing about them is skill.

For a control, drive the same nineteen creatures with the hand-written rule, in the same valley, from the same seed.

$ go run ./cmd/wired -mode herd -herd 24 -years 2 -mind rule | tail -28
    tick   season  alive      eaten    carcass   standing       litter
    1351   summer     19   909.8334     0.0000     107.67       0.0897
    2251   autumn     19  2505.1229     0.0000     112.94       4.8714
    3151   winter     10  2734.2830   360.0000       0.00     353.2494
    4051   spring      0  2734.2830   760.0000     826.99     146.2922
    4951   summer      0  2734.2830   760.0000     546.88       0.1264
    5851   autumn      0  2734.2830   760.0000    1128.00      22.0877
    6751   winter      0  2734.2830   760.0000     982.00       4.3049
    7651   spring      0  2734.2830   760.0000    2029.63       0.8348

  19 creatures started, 19 struck off, 0 still walking after 6750 ticks

  the tick refused an action 9243 times:
    no standing tissue inside reach              5562
    the cell ahead is open water or off the grid   3639
    the store cannot pay for it                    42

  where they stopped, 19 of them:
    on open soil           14
    on the rocky rim        5
    first at tick 2800 on 5,7, last at tick 3293 on 0,3

  the books in grams
    in                       34554.772631      founded, grown and stood up
    out                      34554.772631      standing, walking, flying, lying, spent
    difference                  -0.000000      -1.091e-10, which is the last bits of the adding
    19 creatures struck off at 40 grams a body is 760.000000 grams of carcass
    handed to terra.Bed.Fall                        760.000000 grams

The rule is a far better forager and it kills everything. All nineteen survive the first year and eat 2,734 grams, against 1,976 for the drawn brains over twice as long, and by the winter of the second year there is nothing standing in the valley at all. Then every one of them starves inside five hundred ticks of each other, the first on tick 2,800 and the last on 3,293. Nineteen animals that all want the nearest plant, all the time, strip a twelve by eight valley faster than it grows, and the rule has no line in it about stopping.

Do not take that as the networks winning. They lost seventeen of nineteen and left the valley standing mostly because they were too incompetent to eat it. What the pair of runs shows is a different thing, and a better one: the machinery underneath both is identical. Same table, same check, same phase, and both sets of books close on their own totals to the last bits of the adding. Only the object behind one interface changed, and the valley did something completely different. That is the seam doing its job.

Why the loop is closed

Two mechanisms in this chapter outlive the creatures they were built for, and they solve different problems.

The first is reading a network's outputs as an ordering over a fixed table instead of as values. This is what lets a completely general lump of arithmetic drive a completely specific machine. The network never learns what a sprint is; it produces a number in slot 2, and slot 2 is a sprint because a constant in another file says so. Nothing anywhere converts between the two domains, because there is nothing to convert: an index is an index. And because only the ordering is read, every question about the size of the outputs disappears. They can be any range at all.

The second is that a policy which produces a ranking survives a world that vetoes, and a policy which produces a single answer does not. The check knows three things the network cannot: what the ground is like ahead, whether there is anything within reach, and what the store can pay for. Those are facts about a place, and the row deliberately carries none of them directly. Given a ranking, the veto costs the creature its first choice. Given one answer, the veto costs it the tick. That difference is not a matter of degree, and the twenty-rest tape in the failure box is what it looks like at full strength.

The last thing this chapter owes is a look at the valley. Everything above is a table of numbers about animals nobody can see, and the client has been able to draw this ground since the terrarium volume: water, rim, soil, and every plant grown out of its own grammar. A creature is one blit on top of that.

▣ Build · stage 4 — a creature is two rectangles copied out of the sheet
// The two frames of the walker on the sheet the client has been loading
// since the sprite chapter, and the shadow that goes under both.
const (
	Stand  = 0
	Step   = 1
	Shadow = 2
)

// blit puts one creature into the frame: the shadow first, then the
// walker, standing when its legs are still and mid-stride when they are
// not. The sprite is 16 pixels square and a cell is 16 pixels wide, so
// the top-left corner is the creature's own position less half a cell
// in each direction.
func blit(b *render.Buffer, sh *render.Sheet, c *beast.Beast) {
	x := int(math.Round(c.Pos.X)) - terra.Tile/2
	y := int(math.Round(c.Pos.Y)) - terra.Tile/2
	b.Blit(sh, sh.Frame(Shadow, 0), x, y)
	frame := Stand
	if c.Speed() > 0.01 {
		frame = Step
	}
	b.Blit(sh, sh.Frame(frame, 0), x, y)
}

Nothing in there asks what a creature is thinking. It asks where the body is, in world pixels, and how fast it is going, and both of those are numbers the movement chapters already keep. The shadow goes down first so the walker's transparent pixels let it through, which is the alpha mixing the sprite chapter built and nothing more. Which of the two frames gets picked is the only place the drawing and the controller touch at all, and even that is only through a speed.

▣ Build · capture the valley and its nineteen brains
$ go run ./cmd/wired -mode draw -herd 24 -ticks 120 -shot assets/frames/valley-nineteen-brains.png
wired: 12x8 valley, tick 901, year 1 summer, 12 plants standing at 1517.5 grams

  120 ticks on from midsummer, 19 creatures still walking of the 19 founded
  12 plants standing at 1303.3 grams, 44.0000 grams eaten, 0.0000 in the litter
  4 of the walkers had their legs moving when the frame was taken
  the valley 192 by 128 pixels, 191830241279e65d391e6a6d78871bed59676d8e5013006192da0f39a658dbd0
  wrote assets/frames/valley-nineteen-brains.png at 3 times, 576 by 384
A pixel drawing of the valley at three times size: brown soil with a grey rocky rim around it and a large blue pond through the middle, thin dark green plant stems scattered over the soil, and nineteen small green four-legged creatures with pale bellies standing about on it, each with a soft shadow under it. Several creatures stand out on the grey rim beyond the soil, and none are in the water.
Figure 55.2assets/frames/valley-nineteen-brains.png: a hundred and twenty ticks after the population was founded, every creature drawn with the same two calls. Four of the nineteen were moving when the frame was taken. Several are already out on the rim, where nothing grows, and none of them are in the pond, because the ground rule refuses that step whatever a brain scores it.

One hundred and twenty ticks in, the frame reads as a valley with animals in it, which is about as far as an honest description goes. Forty-four grams have moved from plants into bodies. Nothing has died yet. The creatures are still spread roughly where stream 12 scattered them, and several of them are standing on rock, which the two-year census says is where seven of the seventeen deaths happen. A picture of a valley of untrained creatures looks exactly like a picture of a valley of trained ones, and that is the last reason to trust the census over the frame.

✓ Checkpoint — what the closed loop can now be asked
  • Handed the six scores from a tick and the check's answer for each, say which action happens, and say how that differs from taking the best of the six and testing it afterwards.
  • Explain why adding the same number to all six outputs changes nothing, and use that to say what a squash on the output row would and would not buy.
  • Name the two sizes NewWits refuses to guess at, and describe what a network with five outputs would do to a valley without ever producing an error.
  • Say why a creature with Owed above zero is not put through a forward pass, and roughly what share of ticks that skips in a valley of biters.
  • Shown a tape where the wanted column reads the same action twenty times running, tell an untrained network apart from a broken one using the column beside it.
  • Say why the same view has to reach both a creature's rays and its check, and what happens to a Wits that was never handed one.
⚡ Exercises — try first, then reveal
Exercise 1 — a different set of weights on the same tick. The creature on 3,4 was driven by the first brain off the stream. Ask the eighth with go run ./cmd/wired -mode score -at 3,4 -brain 7 and predict how much of the answer moves before you look.

Everything about the row is identical, because the row is a fact about the valley and not about the brain. Everything about the six numbers is different, because nothing links one draw off the stream to the next. The ranking that comes out is a different order, only one score is crossed out instead of three, and the creature turns left rather than right. The two brains agree on nothing except that walking east scores highest, and the ground refuses that for both of them.

$ go run ./cmd/wired -mode score -at 3,4 -brain 7 | tail -11
     score   -0.1536    0.0539   -0.1272    0.0443   -0.0136   -0.3473

   rank   action      score      check   why not
      1     walk     0.0539    refused   creature 1 at 4,4 cannot walk: the cell ahead is open water or off the grid
      2     left     0.0443    allowed
      3    right    -0.0136    allowed
      4   sprint    -0.1272    refused   creature 1 at 4,4 cannot sprint: the cell ahead is open water or off the grid
      5     rest    -0.1536    allowed
      6     bite    -0.3473    refused   creature 1 at 3,4 cannot bite: no standing tissue inside reach

  the creature does turn left: 1 score crossed out above it
Exercise 2 — put it next to dinner. Cell 3,1 has the biggest plant in the valley beside it. Run the same brain there with go run ./cmd/wired -mode tape -at 3,1 -ticks 20 and see whether an animal that wants to bite everything manages to eat.

It eats nothing at all. Twenty walks in a straight line east, four cells crossed, 26.6 units of store gone, of which 3.2 is the standing body and the rest is the legs, and not one gram taken. The top score on 3,1 is a walk and not a bite, and the ranking never gets past its first entry, because east of 3,1 is open soil all the way. The creature that wanted to bite the world on the pond shore walks away from the one plant it could actually have reached. Position, not disposition, decided both runs.

$ go run ./cmd/wired -mode tape -at 3,1 -ticks 20 | tail -8
     18    7,1     0.0 walk       walk         0.0000   1.2150   0.0000   376.1612
     19    7,1     0.0 walk       walk         0.0000   1.2150   0.0000   374.7862
     20    7,1     0.0 walk       walk         0.0000   1.2150   0.0000   373.4112

  20 ticks: 20 walk
  0.0000 grams eaten, 373.4112 left in the store, standing on 7,1 facing 0.0
  20 forward passes spent, 0 ticks held by an action already under way
  the check crossed out 0 scores over the run, and the tick refused 0
Exercise 3 — run the whole valley on the blunt wiring. The failure box showed one creature for twenty ticks. Run nineteen for two years with go run ./cmd/wired -mode herd -herd 24 -years 2 -blunt and decide from the numbers whether the ranking is a survival improvement.

It is not, and saying so is more useful than pretending otherwise. Three survive instead of two, and the population eats 1,664 grams instead of 1,976. What changes by an enormous margin is the refusal count: 29,388 against nothing at all, more than one refused action for every two forward passes, twenty-one thousand of them a step into water or over the rim. The ranking is a correctness improvement rather than a fitness one. It makes the creature's action be the network's own choice among what was possible, instead of having that choice silently replaced by a rest twenty-nine thousand times.

$ go run ./cmd/wired -mode herd -herd 24 -years 2 -blunt | tail -25
  46399 forward passes spent, 6665 ticks held by an action under way
  the check crossed out 0 scores inside Pick over the run

  the tick refused an action 29388 times:
    no standing tissue inside reach              7860
    the cell ahead is open water or off the grid  21412
    the store cannot pay for it                   116

  where they stopped, 16 of them:
    on open soil            9
    on the rocky rim        7
    first at tick 1605 on 10,5, last at tick 3400 on 11,5

  still walking, and what each of them lived on:
        id     cell  grams eaten        store cells a tick grams in reach
         1     10,2     505.9203     351.7900       0.0000        56.6813
         3     10,2     505.6771     351.7900       0.0000        56.6813
        18      7,1     652.0000     399.5300       0.0000       165.9607

  the books in grams
    in                       44373.483451      founded, grown and stood up
    out                      44373.483451      standing, walking, flying, lying, spent
    difference                   0.000000      0.000e+00, which is the last bits of the adding
    16 creatures struck off at 40 grams a body is 640.000000 grams of carcass
    handed to terra.Bed.Fall                        640.000000 grams

A creature can now see the valley, think about what it saw, do the best thing it is allowed to do about it, and be drawn doing so. Nineteen of them ran for two years inside a tick that also grew plants, moved weather and rotted litter, and every gram was still accounted for at the end of it. What nothing here has measured is the price. Every one of those decisions was 360 multiplications and up to six calls to a check, on top of four hundred ray samples, and the tick has a hundred milliseconds in it of which the creatures were promised half. Nineteen animals will not tell you whether that promise can be kept.