The World Vol 9 · The Village
ch 90 / 105
Chapter 90

The First Villager

The one thing a person needs that every animal already has

The Hollow has a gathering place in the founding document and nobody standing there. Plants and animals already fill the valley, but every animal is still a genome, an evolved controller and a breeding record.

A villager is a body in the same roster, on the same legs, paying the same prices, eating off the same ground and starving on the same clock. The one difference is that Beast.Mind is answered by something that is not an evolved network. The simulation gains no seam at all for a person to exist in it, because the seam has been there since volume five.

The founding document's empty place becomes code only if two facts hold. A person has to exist without being an animal: no genome, no evolved network, no lineage, no compatibility distance and no breeding rule. People also need one action animals lack, because rest, walk, sprint, turn, bite and strike do not let one body hand anything to another.

The first fact costs nothing. The interface every creature is steered through is one method wide:

// internal/beast/act.go, since the network chapter
type Mind interface {
	Pick(row *Senses) Act
}

Twenty-four numbers in, one entry of the table out, and nothing else crosses. A Mind cannot see the valley, cannot reach a plant and cannot spend anything. It was written that way so a three-row network drawn out of a genome could drive a creature without the creature knowing what a network was. Anything at all that can answer that question can drive a body, and the body never finds out what answered.

The second cost is one line of a file and a good deal of care about where the line goes. The action table grows two entries, hand and take, and they are the same transfer written twice: the same parcel, the same price, the same two ticks, and one question asked of two bodies in the opposite order. Giving and taking differ in law and not in physics, and getting that into two short functions that read almost the same is most of what this page is about.

By the end of it the table holds nine entries, a person called Halla is standing on the east shore of the lake at Firstlight handing grain to her neighbours, the grams ledger closes to the last bit over four hundred ticks, and three runs written long before any of this existed come back with every figure where it was. Then there is one measurement, and it is the reason every chapter after this one is arranged the way it is: what a model costs, put beside the hundred milliseconds a tick has.

The eighth entry and the ninth

Start with what moves. This book has no inventory, no items, no coins and no economy, and building one here would be doing another volume's work in the wrong place. What it has had since the fourth volume is a single unit that every living thing is priced in: grams of tissue. A plant stands in grams. A bite takes grams off a stand. A carcass is grams into the litter. The valley's books balance in grams and have balanced in grams in every run this book has printed.

So the goods are grams, and they come out of the store an animal already carries. That needs one function, because a store is measured in energy units, and a gram of tissue turns into Convert of them when it is swallowed. Reading the store back the other way is one division:

// internal/beast/act.go

// Room is what this body could still take in, in grams: the space
// left in the store, at what a gram of tissue is worth to it.
func (b *Beast) Room() float64 { return (b.Kind.Full - b.Store) / b.Kind.Convert }

// Carrying is the store read back in the unit it was bought in: what
// this body holds, at what a gram of tissue is worth to it. A browser
// with a full store of 400 energy units is carrying 100 grams,
// because a gram is worth 4 to that row.
// ...
func (b *Beast) Carrying() float64 { return b.Store / b.Kind.Convert }

Those two are the whole of the crossing between the two units this world prices in, and they exist because a transfer has two bodies in it. What leaves one store and what arrives in the other is the same mass; the energy each of them books it at is each of theirs. That is the same crossing a mouthful already makes, with an animal at both ends of it instead of a plant at one.

How much is a parcel? The row does not carry a number for how much a body can pass to somebody in a tick, and adding one would be a change to Kind, which is a change to what a genome describes. It does carry a number for how much a body's mouth moves in a tick, which is Bite. A parcel crossing Reach cells in one tick is the same mass over the same ground in the same time as a mouthful crossing it, so the two are one number and the eighth and ninth entries need nothing new on the row at all.

▣ Build · stage 1 — two names, one constant, and two rows appended
// internal/beast/act.go
const (
	Rest Act = iota
	Walk
	Sprint
	Left
	Right
	Bite
	Strike
	Hand
	Take
)

// Acts is how many entries the table has, and Fixed is how many of
// them the frozen controller can name. They are two different numbers
// and they were only ever spelled the same.
// ...
const (
	Acts  = 9
	Fixed = 6
)

var Table = [Acts]Move{
	Rest:   {Name: "rest", Ticks: 1, Price: nothing, Allow: always, Needs: "nothing"},
	Walk:   {Name: "walk", Ticks: 1, Price: amble, Allow: ground, Needs: "the cell ahead is not open water"},
	Sprint: {Name: "sprint", Ticks: 1, Price: dash, Allow: ground, Needs: "the cell ahead is not open water"},
	Left:   {Name: "turn left", Ticks: 1, Price: Kind.Wheel, Allow: always, Needs: "nothing"},
	Right:  {Name: "turn right", Ticks: 1, Price: Kind.Wheel, Allow: always, Needs: "nothing"},
	Bite:   {Name: "bite", Ticks: 2, Price: Kind.Chew, Allow: mouth, Needs: "tissue standing inside Reach"},
	Strike: {Name: "strike", Ticks: 2, Price: Kind.Lunge, Allow: prey, Needs: "a living creature of a lower level inside Reach"},
	Hand:   {Name: "hand", Ticks: 2, Price: Kind.Chew, Allow: giving, Needs: "a parcel to give and somebody inside Reach with room for it"},
	Take:   {Name: "take", Ticks: 2, Price: Kind.Chew, Allow: taking, Needs: "room for a parcel and somebody inside Reach carrying one"},
}

// Parcel is how many grams one hand or one take moves between two
// bodies, and it is the mouth's own measure because the row has no
// other. Nothing on Kind says how much of anything an animal can
// ...
func (k Kind) Parcel() float64 { return k.Bite }
$ go run ./cmd/hands -mode table
hands: the action table, nine entries, priced for the row a person is stamped from

  beast.Acts    9   entries in the table
  beast.Fixed   6   scores the frozen controller hands back

  the folk row, read out of configs/village.json: bulk 80 grams at level 1,
  work 0.60, top 0.45 cells a tick, bite 0.50 grams, 4.00 units a gram,
  reach 1 cell, store 800 units full

     action          price   ticks scored by   what has to be true here
   0 rest           0.0000       1 both        nothing
   1 walk           2.4300       1 both        the cell ahead is not open water
   2 sprint         9.7200       1 both        the cell ahead is not open water
   3 turn left      0.8100       1 both        nothing
   4 turn right     0.8100       1 both        nothing
   5 bite           0.3000       2 both        tissue standing inside Reach
   6 strike         9.7200       2 graph only  a living creature of a lower level inside Reach
   7 hand           0.3000       2 graph only  a parcel to give and somebody inside Reach with room for it
   8 take           0.3000       2 graph only  room for a parcel and somebody inside Reach carrying one

  a parcel is 0.5000 grams, which is what this row's mouth moves in a tick
  a hand and a take are charged for that crossing and not for the goods:
  0.60 x 0.50 x 1 x 1 = 0.3000, which is what a bite costs and is the same number
  the goods are moved in apply, out of one store and into another

  a full store of 800.0000 units reads back as 200.0000 grams, at 4.00 a gram
  the parcel is 0.5000 grams, so a full store is 400 parcels
  and handing every one of them over takes 800 ticks, at 2 ticks an action

  the standing body is charged 0.3200 a tick whatever the action is, so one
  transfer is 0.9375 ticks of standing still, and the parcel that moves in it
  is worth 2.0000 units, which is 6.2500 ticks of the same

  the folk row can ever take: rest walk sprint turn left turn right bite hand take
  and never: strike, because nothing in this valley stands below level 1

Read the price column across the last three rows. A bite, a hand and a take all cost 0.3000, and that is one number printed three times rather than three numbers that happen to agree: all three are Kind.Chew, which is this row's own mass moved over its own reach at its own price for a unit of work. The goods are not in that price. They are moved in apply, out of one store and into another, and what the giver is charged for is the crossing.

The last block of the run is the founding cut asked of the row a person is stamped from, and it comes back the way a browser's does, because a person stands at level one and nothing in this valley stands below level one. A villager can do everything an animal can do except hit somebody.

Now the rule, which is where the interesting decision is. A transfer has two ends and both of them have to be there. Somebody has to be inside reach. There has to be a parcel at the giving end. There has to be room for it at the taking end. A hand asks the second question of itself and the third of the other body; a take asks the second of the other body and the third of itself. Nothing else about the two entries differs.

▣ Build · stage 2 — one search, two rules, three refusals
// internal/beast/act.go

// Hands is the body a transfer would cross to and how many grams that
// body brings to it: of every living creature other than this one
// inside Reach, the one with the most of whatever this transfer needs
// from them. A hand needs room, so it goes to the emptiest; a take
// needs goods, so it comes off the fullest. One search, one sentence,
// and the entry decides which end of it this body is on.
// ...
func (b *Beast) Hands(v *View, a Act) (*Beast, float64) {
	n := int(b.Kind.Reach)
	here := b.Cell()
	var best *Beast
	most := 0.0
	for dy := -n; dy <= n; dy++ {
		for dx := -n; dx <= n; dx++ {
			for _, o := range v.Crowd(here.Offset(dx, dy)) {
				if o == b || o.Dead {
					continue
				}
				g := o.Carrying()
				if a == Hand {
					g = o.Room()
				}
				if best != nil {
					switch {
					case g < most:
						continue
					case g == most && o.ID > best.ID:
						continue
					}
				}
				best, most = o, g
			}
		}
	}
	if best == nil {
		return nil, 0
	}
	return best, most
}
// internal/beast/act.go — the two rules, side by side on purpose
func giving(b *Beast, v *View) error {
	o, room := b.Hands(v, Hand)
	if o == nil {
		return ErrNoHands
	}
	if b.Carrying() < b.Kind.Parcel() {
		return ErrNoGoods
	}
	if room < b.Kind.Parcel() {
		return ErrNoRoom
	}
	return nil
}

func taking(b *Beast, v *View) error {
	o, held := b.Hands(v, Take)
	if o == nil {
		return ErrNoHands
	}
	if held < b.Kind.Parcel() {
		return ErrNoGoods
	}
	if b.Room() < b.Kind.Parcel() {
		return ErrNoRoom
	}
	return nil
}
$ go run ./cmd/hands -mode check
hands: the check asked all 9, of a person standing among their neighbours

  Halla is creature 1 on 8,5 at level 1, carrying 200.0000 grams
  Ander is creature 2 on 9,5, carrying 40.0000 grams
  Mose is creature 3 on 8,6, carrying 120.0000 grams
  the richest cell inside their reach is 8,6 at 169.2321 grams of tissue

  action          price   ticks   what the check says
  rest           0.0000       1   allowed
  walk           2.4300       1   allowed
  sprint         9.7200       1   allowed
  turn left      0.8100       1   allowed
  turn right     0.8100       1   allowed
  bite           0.3000       2   allowed
  strike         9.7200       2   creature 1 at 8,5 cannot strike: no creature of a lower level inside reach
  hand           0.3000       2   allowed
  take           0.3000       2   creature 1 at 8,5 cannot take: there is no room at the taking end

  the two searches, on the same tick and over the same cells
  a hand goes to   creature 2, with room for 160.0000 grams, the most inside reach
  a take comes off creature 3, carrying 120.0000 grams, the most inside reach
  one search, one rule: the body with the most of what this end needs

  and the same person alone on 2,6, with nobody inside reach
  hand        creature 1 at 2,6 cannot hand: no other living creature inside reach
  take        creature 1 at 2,6 cannot take: no other living creature inside reach
  as a rule   errors.Is(err, beast.ErrNoHands) is true

  back among the neighbours, carrying 0.2500 grams, which is half a parcel
  hand        creature 1 at 8,5 cannot hand: there is no parcel at the giving end
  as numbers  it wanted 0.5000 grams and found 0.2500: this rule compares two
  take        allowed
  a take is the same rule with the subject swapped, so it is allowed

Halla is carrying two hundred grams, which is everything the row's store holds, so the third question stops her taking anything from anybody: there is nowhere to put it. She can hand, and the hand goes to Ander, who has the most room of the two people inside her reach. Both searches ran on the same tick over the same nine cells and came back with different bodies, and the only thing that differed between them was which end of the transfer was asking.

The last block is the same person carrying half a parcel. The hand is refused for having no goods and the refusal carries two numbers in grams: what the rule wanted and what it found. The strike's refusal, in the table above it, carries none, because a search that found nobody has no pair of quantities to report. Four of the seven rules in this table compare two numbers and three do not, and the struct has always said that a rule comparing nothing leaves those fields at nothing.

The third question is the one that keeps the books, and it is the difference between this entry and a bite. A mouthful that overflows a full store spills, and the grams are gone; that is allowed because the grams came off a plant and the plant is counted separately, so the valley's ledger still closes. A transfer has an animal at both ends. If a parcel arrived at a store with no room in it, this world would be making grams and destroying them inside one tick, and no other rule in the package does that. So the check refuses it and nothing is ever lost in a transfer.

One transfer, two bodies, and three questions in order Two labelled boxes stand side by side: the giving end on the left and the taking end on the right, with an arrow carrying one parcel from left to right between them. Below the boxes three numbered questions run left to right: is anybody inside reach, is there a parcel at the giving end, is there room at the taking end. Under each question is the refusal it produces. Three lines at the bottom say that a hand puts this body at the giving end and a take puts it at the taking end, that the search finds the emptiest neighbour in the first case and the fullest in the second, and that the store is asked for the price before any of the three questions. ONE TRANSFER, AND THE THREE THINGS THE CHECK ASKS the giving end must be carrying a parcel the taking end must have room for one one parcel Bite grams ASKED IN THIS ORDER, CHEAPEST FIRST 1 anybody in reach ErrNoHands 2 a parcel there ErrNoGoods 3 room for it ErrNoRoom hand: this body is the giving end, and the search finds the emptiest neighbour take: this body is the taking end, and the search finds the fullest neighbour the store is asked for the price before any of it, as it is for all nine entries
Figure 90.1 — the two appended entries are one picture read in two directions. The parcel, the price and the two ticks are the same whichever way it goes; what the entry decides is which of the two bodies is carrying and which has room. The three questions are asked in that order because the first is a walk over the cells inside reach and the last two are comparisons on numbers already in hand.

Founding people where the document said they would gather

The founding document is a file of names written at tick zero and read once, and the rule that came with it two volumes ago is that it is never amended. Not one character. A name put down before anything happened is a name nothing that happened afterwards could have argued with, and that is the entire value of having written it early. One of its keys says that people gather at Firstlight, and its note says that nobody is there and nothing stands there. Another says that what changes hands is grain, and its note admits that nothing in the world trades and nothing is priced, and that the word is being written down anyway because it costs one line today and cannot be had at all tomorrow.

Both of those notes are still true of the file and neither is true of the world any more. The document does not change. What changes is that there is now a second file beside it with people in it.

configs/village.json is that file, and it sits beside the founding document in the same embedded directory, so a build carries it and a run reaches for nothing. The top of it is one body row every person is stamped from. The rest is the people, and the prose in each of them is written by a person and is never produced by anything:

▣ Build · stage 3 — a roll, a record, and a package the valley has never heard of
{
  "row": {
    "name": "folk",
    "bulk": 80,
    "full": 800,
    "basal": 0.004,
    "work": 0.60,
    "bite": 0.5,
    "convert": 4.0,
    "reach": 1.0,
    "sight": 12,
    "top": 0.45,
    "turn": 12,
    "trophic": 1
  },
  "people": [
    {
      "name": "Halla",
      "law": "settled",
      "home": {"x": 8, "y": 5},
      "carrying": 200,
      "persona": "Halla came to Firstlight before there was a Firstlight and put her house on the flattest ground she could find. She keeps more grain than she needs and gives the difference away, and she has never once been asked why."
    },
    {
      "name": "Ander",
      "law": "settled",
      "home": {"x": 9, "y": 5},
      "carrying": 40,
      "persona": "Ander lives one cell east of Halla and eats what is in front of him. He is not idle and he is not generous; he is a man who has never had to decide, because so far nothing has been scarce."
    },
    {
      "name": "Mose",
      "law": "settled",
      "home": {"x": 8, "y": 6},
      "carrying": 120,
      "persona": "Mose walks the edge of the standing plants every morning and comes back with the same answer. He takes what he is offered and offers nothing, and nobody at Firstlight has yet decided whether that is a fault."
    }
  ]
}
// internal/village/village.go
type Person struct {
	Name    string    `json:"name"`
	Persona string    `json:"persona"`
	Law     string    `json:"law"`
	Home    sim.Coord `json:"home"`

	// Carrying is how many grams this person is founded holding,
	// which the file writes in grams and not in energy units because
	// grams is what a person can hand to somebody. It is the one
	// ...
	Carrying float64 `json:"carrying"`

	Founded int          `json:"-"`
	Body    *beast.Beast `json:"-"`
}

// Found stands every person in the roll up on their home cell and puts
// them on the roster. It hands back the people with their bodies
// filled in, in the order the file names them.
//
// Founding is a plain loop and draws nothing. A creature is scattered
// over the valley off a stream because nobody wrote down where it
// should be; a villager is put where the file says, because somebody
// did. The roster hands out identities the same way it always has, so
// ...
func Found(v *terra.Valley, roll Roll, r *beast.Roster) ([]*Person, error) {
$ go run ./cmd/hands -mode found -ticks 4000
hands: 12x8 valley, tick 901, year 1 summer, 12 plants standing at 1517.5 grams

  3 people founded from configs/village.json, stamped from the folk row,
  standing on the cells the file gives them, drawn off no stream at all
  the roster holds 3 bodies and the next free identity is 4

  name        id     home      law      store      grams   founded
  Halla        1      8,5  settled   800.0000   200.0000   tick 901
  Ander        2      9,5  settled   160.0000    40.0000   tick 901
  Mose         3      8,6  settled   480.0000   120.0000   tick 901

  what a villager has that an animal has: a body of 80 grams, a store of
  800 units, 12 cells of sight, 0.45 cells a tick at a sprint, level 1,
  a place in the roster and an identity nobody else will ever carry
  what it has not: no genome, no evolved net, no lineage, no row in the
  archive, no place in the compatibility distance and no way to breed

  the one difference is the field volume five put on every creature
  Halla    Beast.Mind is village.Errand
  Ander    Beast.Mind is village.Errand
  Mose     Beast.Mind is village.Errand

  a full store covers 2500 ticks with nothing at all coming in, at 0.3200 a
  tick of standing there. The rule is volume five's and a person is not
  exempt from it, so the run below feeds nobody.

  the run stopped on tick 1641, 740 ticks after the founding
  Halla       -0.3000 in the store,  -0.0750 grams, dead
  Ander      327.2000 in the store,  81.8000 grams, walking
  Mose       325.1500 in the store,  81.2875 grams, walking

  Halla starved on tick 1640 over cell 8,5 and 80 grams of body went
  into the litter, by the rule that has killed every animal in this book

Three lines of that run are the whole argument. Founding three people drew nothing off any stream, because nothing about a person had to be decided at random: the file says where each of them lives and the row says what each of them is made of. The identities are 1, 2 and 3, out of the same sequence an animal's comes from, so a person and a hobb can never be handed the same number. And the field that makes the whole thing possible prints as village.Errand, which is a struct with five settings on it and no weights anywhere.

Then Halla starves. Nothing feeds anybody in that run, she gives grain away until she hits the tenth of a store the errand keeps back, and after that the rent on eighty grams of standing body takes her the rest of the way down. Eighty grams go into the litter on tick 1640 by the same three lines that have killed every animal in this book. Being a person is not an exemption from anything.

The errand itself is the plainest thing that could drive a body. It reads the fan, finds the nearest ray that met a creature, turns toward it if it is off to one side, walks if it is ahead and out of range, and puts the parcel in their hands when it is close enough. If there is nobody in sight, or a giver's store is down at the share it keeps back, it hands the tick to whatever it was given as a fallback, and with nothing given to it that is a rest. That is a policy in about thirty lines of Go with no arithmetic in it more complicated than a comparison, and everything this volume builds after it is measured against what it does.

◆ Note — the number a ray reports and the number the check uses

Reach is counted in cells crossed in the worse of the two directions, so a reach of one cell is the cell underfoot and the eight touching it. A ray measures the straight line. A body standing on a diagonal neighbour is inside a reach of one and is 1.4142 cells away along the ray that found it, so an errand told to act inside one cell would walk into somebody it was already close enough to hand something to. The errand is told the straight-line distance because a ray is what it reads. The two numbers are about the same geometry and they are not the same number.

Which leaves the ledger. Two entries that move mass between two bodies are two new ways for this world's books to stop balancing, and the way to find out whether they do is to run a village and add everything up.

▣ Build · stage 4 — four hundred ticks, and every gram accounted for
// cmd/hands/deal.go — the audit, and it returns a status and not just a table
	bad := 0
	if diff(out+in, moved) {
		fmt.Printf("\n  NO: what crossed is not the parcel a whole number of times\n")
		bad++
	}
	if diff(opened+eaten-burnt-spilt, closing) {
		fmt.Printf("\n  NO: the village's grams are not accounted for\n")
		bad++
	}
	if gone > 0 {
		fmt.Printf("\n  NO: %d body(s) died inside a run that is meant to keep them standing\n", gone)
		bad++
	}
	if bad > 0 {
		fmt.Fprintf(os.Stderr, "hands: %d thing(s) did not add up\n", bad)
		os.Exit(1)
	}
$ go run ./cmd/hands -mode deal -ticks 400
hands: 3 people and 0 animals, 400 ticks, and a ground that stands still

  the parcel      0.5000 grams, which is the folk row's own mouthful
  a transfer      0.3000 units to make, 2 ticks to be over
  the giver       Halla, and every other person takes
  the errand      hand or take inside 1.4142 cells along a ray, turn or walk
                  outside it, and stop giving below 10% of a full store

  name       at first       room
  Halla      200.0000     0.0000
  Ander       40.0000   160.0000
  Mose       120.0000    80.0000

  name        at last       room changed by
  Halla       16.2250   183.7750  -183.7750
  Ander       47.5000   152.5000     7.5000
  Mose       171.3400    28.6600    51.3400

  what the village asked for and what the check allowed
  action           asked       done
  rest               447        446
  turn left            4          4
  hand               353        177
  take               396        198
  a choice the check refuses costs the tick and is spent resting, so the
  rest row holds the refusals as well as the rests that were asked for
  the check refused nothing over 400 ticks

  what crossed, in grams
  handed over                             88.500000
  taken                                   99.000000
  together                               187.500000
  which is 375 parcels of 0.5000         187.500000

  the roster's own books, in grams
  every body opened carrying             360.000000
  they ate off the standing plants         0.000000
  the ticks charged them                 124.935000
  a full store had no room for             0.000000
  they closed carrying                   235.065000
  opened plus eaten less charged and spilt       0.000000

  it closes. Every gram that left a store arrived in another one, and
  what the roster holds at the end is what it started with, plus what it
  ate, less what 400 ticks charged it for being alive in them

Three hundred and seventy-five transfers happened and the parcel is half a gram, so 187.500000 grams crossed between the three of them. The village opened carrying 360, closed carrying 235.065000, and the four hundred ticks charged it 124.935000 for being alive in them. Those two figures subtract to nothing at the sixth decimal place, and that is the claim: a transfer moves mass about inside the village and makes none of it.

The middle block is where the design shows. Halla asked to hand 353 times and did it 177 times, because a hand takes two ticks and the second one belongs to the hand already under way. Ander and Mose asked to take 396 times and did it 198. Nothing was refused over four hundred ticks, and that is not the check being lax: the errand only asks for a transfer when it can see a body inside its reach, so the choices it makes are choices the check was always going to allow. A driver that ranks and checks before it settles never hands the tick an action the tick would refuse.

The last thing that run says is about the audit and not about the village. Every one of those comparisons returns a non-zero status when it fails, and the second has been made to fail on purpose: raise what arrives in a transfer by a thousandth and the run prints its NO and exits 1. A table of numbers for a person to read is a report. A check has to be able to stop the run it is watching.

One more thing about that run, and it is a piece of machinery this page did not have to build. A transfer writes a number onto a creature that is not the one taking the tick, which until the strike was appended nothing in this world did. A body handed a parcel after its own turn has closed can be pushed to nothing on somebody else's tick, and the phase already walks the roster once more, after everybody has stepped and before anything is buried, looking for exactly that. The sweep was written for the strike. It needed no edit at all to cover this.

▣ Build · stage 5 — the seal, with a floor under it
// internal/village/rule_test.go
var sealed = []string{"sim", "terra", "beast", "gene", "mind"}

// ...
func TestNoSimulationPackageImportsVillage(t *testing.T) {
	const forbidden = "theworld/internal/village"
	// ... a walk over every .go file in the five packages ...
	if checked < 70 {
		t.Fatalf("only %d files read across %v: the walk found less than the tree holds", checked, sealed)
	}
	t.Logf("%d files read across %d simulation packages, and not one of them names it", checked, len(sealed))
}
$ go test ./internal/village/ -run 'TestNoSimulationPackageImportsVillage|TestTheRollIsThreePeopleOnGroundTheValleyHas' -v
=== RUN   TestNoSimulationPackageImportsVillage
    rule_test.go:66: 78 files read across 5 simulation packages, and not one of them names it
--- PASS: TestNoSimulationPackageImportsVillage (0.00s)
=== RUN   TestTheRollIsThreePeopleOnGroundTheValleyHas
--- PASS: TestTheRollIsThreePeopleOnGroundTheValleyHas (0.00s)
PASS
ok  	theworld/internal/village	0.004s

Seventy-eight files across the five packages that make up the simulation, and not one of them names the package the people live in. The floor matters more than the walk: a check that scans a set and finds nothing passes cheerfully, and a test that opened the wrong directory would report the same clean answer as a test that opened the right one. Seventy is the number this test refuses to go under, and seventy-eight is what it read.

The eight tests the two entries needed are pinned to their own names for the same reason every quoted test run in this volume is: these packages are going to collect tests from a dozen chapters, and a run with no -run on it quotes whatever the package holds on the day somebody replays the page.

$ go test ./internal/beast/ -run 'TestTheTableIsNineAndTheControllerIsSix|TestAHandAndATakeCostWhatABiteCosts|TestAStoreReadsBackInGrams|TestATransferIsRefusedWithNobodyToMakeItWith|TestATransferIsRefusedWithNoParcelToMove|TestAParcelIsRefusedWithNowhereToPutIt|TestGivingAndTakingAreOneTransfer|TestAParcelGoesToTheEmptiestHandAndComesFromTheFullest' -v
=== RUN   TestTheTableIsNineAndTheControllerIsSix
--- PASS: TestTheTableIsNineAndTheControllerIsSix (0.00s)
=== RUN   TestAHandAndATakeCostWhatABiteCosts
--- PASS: TestAHandAndATakeCostWhatABiteCosts (0.00s)
=== RUN   TestAStoreReadsBackInGrams
--- PASS: TestAStoreReadsBackInGrams (0.00s)
=== RUN   TestATransferIsRefusedWithNobodyToMakeItWith
--- PASS: TestATransferIsRefusedWithNobodyToMakeItWith (0.01s)
=== RUN   TestATransferIsRefusedWithNoParcelToMove
--- PASS: TestATransferIsRefusedWithNoParcelToMove (0.01s)
=== RUN   TestGivingAndTakingAreOneTransfer
--- PASS: TestGivingAndTakingAreOneTransfer (0.01s)
=== RUN   TestAParcelGoesToTheEmptiestHandAndComesFromTheFullest
--- PASS: TestAParcelGoesToTheEmptiestHandAndComesFromTheFullest (0.01s)
=== RUN   TestAParcelIsRefusedWithNowhereToPutIt
--- PASS: TestAParcelIsRefusedWithNowhereToPutIt (0.01s)
PASS
ok  	theworld/internal/beast	0.049s

The one to read the name of twice is TestGivingAndTakingAreOneTransfer. It sets the same two bodies up twice, hands a parcel one way and takes the same parcel the other way, and asserts that the parcel is the same size both times, that the tick charges the same, and that the charges always land on whoever asked. A giver pays for the parcel and for the tick. A taker's source pays for the parcel and nothing else, and the taker pays for the tick out of what arrives. That asymmetry sits on whoever did the work, and never on the parcel.

Three runs that had to come back unchanged

Widening the action table is the change this book once said could not be survived. The reason is arithmetic, and it is the reason the two constants at the top of act.go are two constants. Every founding brain in every run in this book is drawn off a seeded stream, a draw is a request for the next number in that stream, and how many numbers a job takes is part of the job. Make the frozen controller as wide as the table and every founding animal spends a different count off the stream, so the second animal founded reads a brain that starts somewhere else and the whole valley is a different valley wearing the same seed.

beast.Acts is the table's width and beast.Fixed is how many scores the three-row network hands back. Fixed does not move. It has been six since the wiring chapter, everything that builds or ranks that network says Fixed, and the block a genome carries is 378 numbers today for the same reason it was 378 numbers two volumes ago. So here are three runs, none of them written by this page, and all three of them from before the table had eight and nine entries in it.

The ground first, which has no creatures in it at all. A thousand valley-years of terrarium with an empty creature phase hooked into every one of its three million six hundred thousand ticks, folded into two digests: one over the ground and everything standing on it at the end, one over a census taken every midsummer of all thousand years.

$ go run ./cmd/books -mode keep -years 1000
books: seed 5, 1000 years, an empty roster hooked into every tick

  world    df1c117e69bdf157   the terrarium's own, unmoved
  census   75c77a67f6f430bb   the terrarium's own, unmoved

Three and a half minutes of arithmetic for two digests. Nothing this page touched goes near seed flight, germination, plant death, moisture or nutrient, and the point of running it is that the page does not have to say so.

Then the animals, and this is the one that would catch a mistake in the constants. Nineteen creatures founded on the herd stream, each stamped out of an identity genome, each handed a brain of its own, two years of valley with nothing registered into the breeding seam. Every one of them is a six-wide ranking asked about a nine-entry table.

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

  19 creatures founded on stream 12, each stamped from an identity
  genome and given a brain of its own off stream 14
  beast.Roster.Born is nil: nothing has registered a breeding pass into it

                                              this run   before the genome   holds
  creatures founded                                 19                  19   yes
  creatures struck off                              17                  17   yes
  still walking after 6750 ticks                     2                   2   yes
  first death                         tick 1044 on 9,5    tick 1044 on 9,5   yes
  last death                         tick 3400 on 11,5   tick 3400 on 11,5   yes
  grams in                                46567.944597        46567.944597   yes
  grams out                               46567.944597        46567.944597   yes

  the two ledgers differ by -1.455e-11, which is the last bits of the adding

Seventeen starve, on the ticks they have always starved on: the first over cell 9,5 on tick 1044 and the last over 11,5 on tick 3400. The grams close in and out at 46567.944597. The right-hand column is not somebody copying the left-hand one; those figures are constants inside the bench and the word at the end of each line is a comparison the program made, and the column is headed for the change that bench was written to survive.

The third is neither the ground nor a valley. Sixty-four genomes drawn off their own stream, four trials each, scored on grams eaten, every scorecard folded into one digest. A scorecard carries one column per entry a creature could put a score on, so it is the run that would catch a card that quietly grew two columns.

$ go run ./cmd/score -mode spread | tail -10
  genomes that scored nothing whatever             26

  grams the generation ate between them     1573.1642
  grams of fodder it was offered          120320.0000
  the share of the larder it found              1.31%
  trials that ended in a store at nothing          129
  creature-ticks over the ring of water          1885
  creature-ticks past the last cell                 0

  digest of the scored generation      e3cd4c94f2fa1612

The generation still eats 1573.1642 grams between them, still finds 1.31% of the larder, and still folds to e3cd4c94f2fa1612. Three runs, one changed foundation, and not a figure out of place on any of them.

Now the part that did move, because saying nothing moved would be false and the honest thing to do with a break is to print it. A wiring that a lineage grows is built at the table's own width, not the controller's, and it always was. Two more entries is two more output nodes for it to be born with.

$ go run ./cmd/hands -mode widths
hands: what two more entries do to a wiring, and what they do not

  the frozen controller  24-12-6, 378 weights, unmoved
  a flat genome          395 numbers, unmoved

  the opening graph                      at 7 out   at 9 out
  nodes                                        39         41
  links, every input to every output          224        288
  biases, one on each output                    7          9
  MIND genes                                  231        297

  a founding browser, after the cut      at 7 out   at 9 out
  links                                       144        192
  biases                                        7          9
  MIND genes                                  151        201
  numbers one founding draws off 14           151        201
  genes in the whole genome                   168        218

  the browser keeps every nerve the wider table gives it, because the two
  entries it gains are two entries any body can take. The seventh was not:
  a browser can never strike, so the founding cut took those 24 links back
  and left one bias behind. It takes nothing back here, and the difference
  is 48 links and 2 biases: 50 more genes on every genome in every
  lineage that grows from here, copied and crossed and mutated at every birth

  a founding hunter keeps the strike as well: 216 links, 9 biases, 225 genes
  and the two rows now differ by the 24 links into the one output a
  browser can never score

Hold that against what the seventh entry did, because the mechanism is identical and the answer comes out the other way round. The seventh entry was the strike, a browser stands at level one and nothing in this valley stands below level one, so a browser can never strike; the founding cut asks the row which entries it could ever take and took the twenty-four links into that output straight back out. The browser paid one bias for the seventh entry and nothing else.

The eighth and the ninth are two entries any body can take. The founding cut asks the same question, gets the opposite answer, and takes nothing back. Forty-eight links and two biases, which is fifty more genes on every genome in every lineage that grows from here, copied at every birth, crossed at every crossing and mutated at the usual rate. So no run in this book that was driven by a wiring reproduces in this module, and no figure from one may be set beside a figure from here in either direction. That is a real cost, it is countable, and the run above is what counts it.

⚠ Worked failure — give the villagers the mind every animal has

The temptation takes about a minute to give in to. There is already a thing in this module that answers Pick, it has driven every creature for four volumes, and a villager is a creature. Draw each of the three a genome, wire its graph to its body, and the people are running with no new code at all. It compiles, it vets clean, and it runs.

// cmd/hands/found.go — behind -evolved, and off in every founding this book ships
func heads(people []*village.Person, seed uint64) {
	brains := mind.Brains(seed)
	spent, genes := 0, 0
	for _, p := range people {
		g := gene.Root(brains, gene.NewMint(gene.Wide, beast.Acts), 0)
		gene.NewHead(g, p.Body)
		spent += g.Wire.Genes()
		genes = g.Len()
	}
	// ...
}
$ go run ./cmd/hands -mode found -ticks 4000 -evolved | tail -11
  a full store covers 2500 ticks with nothing at all coming in, at 0.3200 a
  tick of standing there. The rule is volume five's and a person is not
  exempt from it, so the run below feeds nobody.

  the run stopped on tick 1013, 112 ticks after the founding
  Halla      799.0600 in the store, 199.7650 grams, walking
  Ander       -0.0400 in the store,  -0.0100 grams, dead
  Mose       647.3600 in the store, 161.8400 grams, walking

  Ander starved on tick 1012 over cell 9,5 and 80 grams of body went
  into the litter, by the rule that has killed every animal in this book

Two things went wrong and only one of them is visible in the last four lines. Ander starves on tick 1012, a hundred and twelve ticks after being founded. Driven by the errand he was still walking seven hundred and forty ticks in, carrying 81.8000 grams, and the person who starved in that run was the one giving everything away. A drawn wiring has no opinion about anything; it ranks nine outputs off a graph nothing has selected, and the expensive ones win as often as the cheap ones. Ander opened carrying forty grams and spent them moving.

The other one is three lines above the deaths and it is the reason this is a failure rather than a poor policy. Founding three heads spent 603 numbers off the brain stream and gave each person a genome of 218 numbers. A genome is a row in the archive, a place in the compatibility distance, a lineage, a thing that crosses with another thing and produces a third, and driving a body is the least of what it does. Handing a person one does not give them a mind; it makes them an animal that happens to be standing in a house. And it spends numbers off a stream that the founding of a village had, until that flag was set, spent none of.

The symptom is a starved person. The cause is one line back: a driver drawn out of a genome comes with a genome. What a villager needs is the interface, and the interface never asked for one.

What a thought costs, against the hundred milliseconds a tick has

Everything above runs in Go over numbers in memory and finishes inside a tick with room to spare. The interesting question about a person is what happens when the thing answering Pick is a language model in another container instead of a struct with five settings on it. So measure it, at this world's own pace, before anything is designed around it.

A tick is a hundred milliseconds because The World runs at ten ticks a second, and it has run at ten ticks a second since its first volume. There are three kinds of call a village could make: turning a line of text into a row of numbers, asking a small model for a next step, and asking a bigger model for something a person is going to read. The bench makes all three against the pinned models, warms each one with a call it does not time, then times three round trips and prints the middle.

⚙ Tool — the model server, and where the numbers below came from

The server is Ollama in a podman container on a bridge created with --internal, holding one model in memory at a time, with the three model files already on a named volume. Nothing below downloads anything. The container the Go code runs in is on the same bridge and has no other road out, which is why the command in front of every one of these runs is a podman exec and not a go run.

▣ Build · stage 6 — three round trips, and the pace they were taken at
// cmd/hands/cost.go
	prompt, at, who := situation()
	sum := sha256.Sum256([]byte(prompt))
	// The seed is the tick and who is deciding, added, and it is
	// explicit for the reason every stochastic thing in this book has
	// taken a seed: a request with no seed on it is a request whose
	// answer nobody can ask for twice.
	seed := at + who
	// ...
			said, err := c.Generate(ctx, lang.Ask{
				Model: m.Name, Prompt: prompt, Limit: j.limit,
				Context: held, Temp: 0, Seed: seed,
			})
$ podman exec -w /bench world-go go run ./cmd/hands -mode cost
hands: three model calls, measured against the tick

  the pace           10 ticks a second, so a tick is 100ms
  the server         world-lm:11434, one model resident at a time
  the context        4096 tokens
  the prompt         439 bytes, sha256 c9e10362c7a8427d
  the temperature    0.00, so an answer is a function of the seed
  the seed           5402, which is tick 5401 and the person deciding
  the timing         one warm-up that is not timed, then 3 timed round trips
  the village        24 people, for the arithmetic at the bottom

  call          model                           pinned at   limit
  an embedding  nomic-embed-text:v1.5            970aa74c       -
  a plan        qwen2.5:0.5b-instruct-q4_K_M     c5396e06      48
  a line        qwen2.5:7b-instruct-q4_K_M       2bada8a7      24

  call              in       out  stopped     least    middle      most  answered
  an embedding       -  768 wide        -     108ms     109ms     109ms   the cpu
  a plan           168        14     stop     326ms     328ms     329ms   the cpu
  a line           168        24   length    3.839s    3.841s    3.867s   the cpu

  the same three against the tick, at 10 ticks a second
  call               ticks   which is
  an embedding         1.1   0.1 seconds of world
  a plan               3.3   0.3 seconds of world
  a line              38.4   3.8 seconds of world

  the pace at which each of these would be exactly one tick
  an embedding        9.22 ticks a second
  a plan              3.05 ticks a second
  a line              0.26 ticks a second
  this world runs at 10, so not one of them fits inside a tick

  one worker, 24 people, and the middle figures above
  one plan of the length this one came to         328ms        3 ticks
  a plan each, round the village once            7.878s       79 ticks
  one line from the hero model                   3.841s       38 ticks

  and the ceiling, which is arithmetic off the rate above and not a run:
  a plan that ran to all 48 of its tokens        1.125s       11 ticks
  a plan each at that length                    27.009s      270 ticks

Every duration in that block was measured here, on an eight-core AMD Ryzen 7 3700X with 30 GB of memory, rootless podman, and the model server answering on the processor with no graphics card in use; yours will differ, and the last column is the server's own answer about which piece of hardware did the work and not this bench's assumption. The prompt's 439 bytes, its sha256, the three pinned digests and every division underneath will not differ. Nothing the models wrote is on this page: the three calls came back with a row of 768 numbers, a plan and a sentence, and what is being measured is how long they took.

The three configurations are three configurations and not one. Different models, different quantizations, different token limits, and one of them is an embedding, which is a different kind of work from a generation. No sentence on this page sets any of those three durations beside either of the others as though they were comparable measurements of one thing. What they are comparable to is the tick, and the tick is the same hundred milliseconds for all three.

∑ Math Interlude — a round trip, in ticks, at a stated pace

The world runs at ten ticks a second. Ten ticks in one second means one tick is one second divided by ten, which is a tenth of a second: a hundred milliseconds. Every figure below is that number and one measured duration.

The plan's middle round trip was 328 milliseconds. How many ticks is that? Divide 328 by 100 and the answer is 3.28, which the run prints as 3.3. The embedding was 109 milliseconds, so 1.09 ticks, printed as 1.1. The line from the bigger model was 3.841 seconds, which is 3,841 milliseconds, so 38.4 ticks. Not one of the three fits inside one tick, and the cheapest of them misses by not quite a tenth of one.

Turn that round and the number gets easier to remember. At what pace would one of these round trips be exactly one tick? One second divided by 328 milliseconds is 3.05, so a world running at three ticks a second could almost fit one plan into a tick. This world runs at ten. For the line it is one second divided by 3.841 seconds, which is 0.26 ticks a second, or one tick every four seconds.

And the arithmetic that decides the size of a village. One worker asking one model at a time, twenty-four people, one plan each: 24 times 328 milliseconds is 7.872 seconds, and the run prints 7.878, because it multiplies the duration it measured and rounds afterwards where this paragraph rounds first. Either way it is 79 ticks, so a village of that size gets round itself in about eight seconds of world. That is with an answer that stopped at 14 of the 48 tokens it was allowed. At the same rate a plan running to all 48 would be 48 divided by 14, times 328 milliseconds, which is 1.125 seconds, and twenty-four of those is 27.009 seconds, or 270 ticks.

The same three lines in symbols:

T = 1 ÷ f

ticks = R ÷ T

round = n × R

The middle one is the whole of it, and it has two numbers in it. A figure in ticks with only R named is half an answer, and the half that is missing moves the answer a long way: 3.841 seconds is 38.4 ticks in this world, and in a world running unwatched at a thousand ticks a second, where a tick is one millisecond, the same 3.841 seconds is 3,841 of them. A figure given in ticks names the pace it was taken at, every time, or it is not a figure.

fticks a second the world is being run at; 10 for every figure on this page
Thow long one tick is; 100 milliseconds here
Rone round trip to a model, measured start to finish, in the same units as T
npeople in the village, each getting one call, with one worker asking
a × ba multiplied by b
a ÷ ba divided by b

Three consequences fall out of that table and none of them is a matter of taste. The first is that nothing inside a tick can call a model. The rule this book has been under since it grew a database was that nothing inside a tick opens a transaction, because a tick that can wait on a disk has no budget any more. The cheapest of these three calls takes 1.1 ticks and the dearest takes 38.4, so a tick that waited on either of them would be over and gone before the answer came back.

The second is that most of what a villager does cannot involve a model at all. Twenty-four people and one worker is a call each every eight seconds at the length that answer came to, and about half a minute at the length it was allowed. In between those calls somebody has to produce an action every hundred milliseconds, and the thing that produces it has to never fail and never wait. This page's errand is a first draft of that.

The third is about which model answers. The server holds one model in memory at a time, so a call to the bigger one costs loading it, and loading the smaller one back again afterwards, on top of a round trip that is already 38.4 ticks. Any design that reaches for the bigger model has to be a design that knows it is paying for the reach, and the price is not only the round trip.

Why method signatures define the seam

Take the valley away and what is left is a pattern that turns up wherever a program has to let something new drive something old. There is a machine. There is a thing that decides what the machine does next. Somebody has to write down what passes between them, and the size of what they wrote down is the size of everything that will ever be possible across that join.

Volume five wrote down twenty-four numbers in and one action out. It was written for a three-row network, and at the time that was the only thing on the far side of it. What makes it hold today is what it left out. It does not say how many entries the far side can score, so a controller drawn six wide goes on driving creatures in a world whose table has nine in it. It does not say what the far side is made of, so a struct with five settings on it drives a body exactly as well as 378 drawn weights. It does not hand over the valley, a database handle, a clock or a socket, so nothing on the far side can do anything except read numbers and answer.

That last part is what makes this chapter's claim checkable rather than hopeful. The five packages that make up the simulation do not import the package the people live in, a test walks all seventy-eight of their files to say so, and the walk has a floor under it so that finding nothing cannot pass for finding nothing wrong. Adding people to this world cost the valley no seam whatever, and the evidence is a diff that has nothing in it.

The second thing here generalizes past interfaces and it is about constants. Two entries appended to a table sorted every line in the module that names the table's width into one of two piles: lines about how many things exist, and lines about how many things a machine built when the world was narrower can express an opinion on. Those two were the same number for two volumes and there was no way to tell them apart until something made them disagree. The frozen controller's pile did not move and its runs are byte-identical. The other pile did, and its cost is on the page above in links and biases and genes. When a shared constant is about to be widened, the question to ask of every line that reads it is which of those two things it means.

And the third is about units, and it is the one that will keep coming back. A duration is a fact about a machine. A tick is a fact about a design. Divide one by the other and you get a number that sounds like it is about the world, and it is only about the world if the pace is standing next to it. The same 328 milliseconds is 3.3 ticks in a world watched at ten a second and 328 of them in a world running unwatched at a thousand a second, and a hundred-fold difference is not a rounding. Neither of those two figures is wrong. A figure quoted without its pace is.

✓ Checkpoint — the table at nine, the person at level one, and the three durations
  • Given a body carrying 200 grams standing next to one carrying 200 grams with the same row, say which of hand and take the check refuses, which of the three questions refuses it, and what the two numbers in the refusal are.
  • Work out what a parcel costs a body with twice the founding villager's bite and the same work factor, and say whether the price of a take changes when the body it takes from has a different Convert.
  • Explain why Hands ranks its candidates in grams and not in energy units, and what would go wrong in a valley whose two rows priced a gram differently.
  • Say why the founding cut took twenty-four links back when the seventh entry was appended and takes nothing back when the eighth and ninth are, using only the row's trophic level to explain it.
  • Given a round trip of 328 milliseconds, work out the number of ticks at ten ticks a second and at a thousand ticks a second, and say which of those two figures is allowed on a page with no pace beside it.
  • Name the piece of the creature phase that a transfer needs and that this chapter did not have to write, and say what would go wrong without it.
⚡ Exercises — try first, then reveal
Exercise 1 — put animals in the village. Scatter eight hobbs into the same roster as the three people and run the ledger again. Predict whether the transfers still balance, and whether a person can hand a parcel to an animal, before you run it.

Eight browsers go on stream 12 into the same roster, driven by the hand-written rule from the network chapter, and the books are kept over every body standing, not over the three people, because a parcel crosses to whoever is inside reach:

$ go run ./cmd/hands -mode deal -ticks 400 -crowd 8 | tail -17
  what crossed, in grams
  handed over                             87.500000
  taken                                  199.500000
  together                               287.000000
  which is 574 parcels of 0.5000         287.000000

  the roster's own books, in grams
  every body opened carrying            1060.000000
  they ate off the standing plants       197.074142
  the ticks charged them                 404.086563
  a full store had no room for            98.059471
  they closed carrying                   754.928108
  opened plus eaten less charged and spilt       0.000000

  it closes. Every gram that left a store arrived in another one, and
  what the roster holds at the end is what it started with, plus what it
  ate, less what 400 ticks charged it for being alive in them

It closes at 0.000000 with eleven bodies on the roster, 287 grams crossing between them, 197.074142 grams coming in off the standing plants and 98.059471 grams spilling out of stores that had no room for a mouthful. It closes for a reason the code states plainly: Hands walks View.Crowd, which hands back every creature standing on a cell, and asks each of them two questions, how much are you carrying and how much room have you. Neither question is about being a person.

So a villager will hand grain to a hobb, and the hobb will be several grams better off. The action table does not know what a person is and this page is not going to teach it: Hand and Take are two bodies and a parcel, and every rule about who ought to be allowed to do what to whom lives outside internal/beast entirely.

Exercise 2 — break the audit on purpose. Make a parcel arrive a thousandth larger than it left, by multiplying what the taking end receives by 1.001 in apply, and run -mode deal again. Say what you expect the program to print, and what you expect it to exit with.

The last line of the books stops being 0.000000 and becomes -0.187500, the run prints NO: the village's grams are not accounted for, and the program exits 1 with a line on standard error. A thousandth of a parcel is a two-thousandth of a gram, three hundred and seventy-five times, and the audit finds it.

That is the point of doing it. The only way to find out whether an audit would ever catch anything is to give it something to catch, and an audit nobody has ever seen fail is an audit nobody has tested. Put the multiplication back and the last line goes to nothing again.

Exercise 3 — price a village you are allowed to run. Using only the run in stage 6, work out the largest village that could get a plan each inside one valley-minute with one worker, both at the length that answer came to and at the token limit it was allowed. Then hand the number to the bench.

A valley-minute at ten ticks a second is 600 ticks. A plan of the length that one came to is 328 milliseconds, which is 3.28 ticks, and 600 divided by 3.28 is 182.9, so a hundred and eighty-two people. At the ceiling, where a plan runs to all 48 of its tokens, one plan is 1.125 seconds or 11.25 ticks, and 600 divided by 11.25 is 53.3, so fifty-three.

-folk is a flag and the bench does that division for you. Its timings below are a fresh measurement and a few milliseconds off the ones in stage 6, so where the last figure falls against six hundred is not something to predict; on this run it fell on it:

$ podman exec -w /bench world-go go run ./cmd/hands -mode cost -folk 53 -runs 1 | tail -8
  one worker, 53 people, and the middle figures above
  one plan of the length this one came to         330ms        3 ticks
  a plan each, round the village once           17.511s      175 ticks
  one line from the hero model                   3.833s       38 ticks

  and the ceiling, which is arithmetic off the rate above and not a run:
  a plan that ran to all 48 of its tokens        1.133s       11 ticks
  a plan each at that length                   1m0.037s      600 ticks

Both of those village sizes are about one machine on one afternoon. What travels is the method: measure the round trip, divide by the tick, and name the pace every time you write the answer down.

There are three people standing at Firstlight, they can put grain into each other's hands, and the thing that decides what they do next is a policy with five settings on it that never fails and never waits. The measurement at the end of this chapter says why that policy is not a placeholder: a call to a model is tens of ticks at best, the world produces an action every hundred milliseconds whatever happens, and those two facts have to live in the same program without either one stopping the other. Arranging that is the next thing to build.