Senses a Parent Never Had
Unused sense channels
A creature reads twenty-four numbers before it decides anything, and every one describes the animal or what stands in front of it. The eight ground columns that follow have carried nothing. Fill the eight unused columns from the ground, scale them into the same span as the other senses, and charge upkeep for every channel the wiring reads.
The bill is half a percent of the energy a gram of body costs, once per channel, for the whole life of the creature. A channel with no incoming link costs nothing, and a channel a lineage keeps must pay for itself in food, mates or survival.
Free senses make every successful animal carry every instrument the package ever gains. That erases the difference between an inherited organ and an unused column waiting in the row.
The ground can say enough to matter: moisture, slope, standing tissue and the local crowd, each scaled before it reaches a controller. The scaling is as much part of the sense as the number itself, because a weight does not have to know whether it is reading litres, grams or neighbours.
The chapter cuts the eight channels out of the founder graph, lets mutation reconnect them, and runs sixteen years of a valley that can hear the ground. The result is a costed organ, not a free column.
Every run below founds its creatures on 144 links instead of 192 and switches on eight channels that used to be constant zero. Both changes affect what an animal does on the first tick it is asked, so the valley on this page is not the valley the wiring chapter ran. No count, curve or pedigree here may be set beside one of that page's. Seed 5 still cuts the same ground, scatters the same twenty-five animals onto the same cells and reads the same weather off the same calendar.
Everything else is untouched, and the two things this page changes are switches that default to off. A pool that leaves them off reads the numbers it always read.
Ground channels and scaling
Numbering the eight is the first decision and it is permanent. A link carries the number of the node it comes from, so two runs that disagree about which channel node 27 is are two runs that cannot be compared, and a genome out of one of them is nonsense in the other. The order below is written down once and never moved.
// internal/gene/sense.go
// The eight channels of the evolved row that no body fills in. Package
// beast writes the first twenty-four and knows nothing about these:
// they are readings taken off the cell a creature is standing on, off
// the calendar and off the creature's own account, and every one of
// them is scaled into -1 to 1 like the twenty-four in front of it.
//
// The order is the contract, the way the first twenty-four are, and for
// the same reason: a link carries the number of the node it comes from,
// and two runs that disagree about which channel node 27 is are two
// different worlds.
const (
Steady = beast.Inputs + iota // 24 a constant 1.00, and the only free one
Tissue // 25 standing tissue on the cell underfoot
Damp // 26 moisture in that cell
Lying // 27 litter lying on it
LyingX // 28 the litter slope going east
LyingY // 29 and going south
Warmth // 30 the season, coldest at -1 and hottest at 1
Spare // 31 the store, against the price of one child
)
// Organs is how many of the eight carry a bill: everything from Tissue
// up. The steady channel is free because there is no organ on the end
// of it. A creature that reads a constant is reading nothing about the
// world, and charging upkeep for one would be charging an animal for
// having a number.
const Organs = Wide - Tissue
// Upkeep is what one channel adds to a creature's Basal factor, which
// is the energy one gram of its body costs it every tick of its life.
// Half a percent is not a number anybody measured, and the page says
// so: it is the smallest bill that is still a bill, chosen so that all
// seven together come to three and a half percent and a reader can do
// the arithmetic without a calculator.
const Upkeep = 0.005
// Sense is how one valley's creatures read the ground: whether the
// eight channels carry anything at all, what the readings are scaled
// against, and whether an organ is charged for.
//
// It is one struct rather than four fields on the pool because all four
// have to travel together from the pool to every driver it makes. A
// valley whose ground speaks to half its animals is not a valley, it is
// a bug.
type Sense struct {
// On is whether the eight channels are filled in at all. With it
// off they stand at nothing on every tick, every link out of them
// multiplies by zero, and the run is the run a valley made before
// the ground could say anything.
On bool
// Scale is what the readings are divided by: one stated full cell
// per field, exactly as the twenty-four in front of them use.
Scale beast.Scale
// Loud is the eight written down as they come off the world, in
// grams and moisture units and energy units, with nothing scaled
// and nothing clamped. It is kept behind a flag so what an unscaled
// input does to a controller can be run instead of described, and
// it is false in every valley this book ships.
Loud bool
// Free is the channels switched on with no bill attached, so an
// organ costs its owner nothing. It is the run the billed one is
// compared against and not a run this book ships.
Free bool
}
Channel 24 is a constant and carries no bill, and both halves of that are deliberate. A node that always hands over 1.00 gives a graph a second bias it can grow towards whichever output it likes, which is useful to be able to grow and free to compute. It is also not a sense: nothing about the world reaches an animal through it, so there is no organ on the end of it to charge for. Billing a creature for a constant would be billing it for owning a number.
The other seven are readings, and a reading arrives in whatever units the thing being read happens to keep. Litter is grams and runs to hundreds. Moisture is the ground's own unit and runs to about one. The store is energy units and runs to four hundred. A controller's weights are all drawn out of one span, so a channel arriving a hundred times the size of its neighbours is a channel shouting over them, and nobody chose that; it fell out of the units. Every one of the seven is therefore divided by a stated full cell of its own field and held inside −1 to 1, exactly as the moisture and tissue gradients have been since a creature first read one.
// internal/gene/head.go
// ground fills the eight channels past the twenty-four a body reads off
// itself. Three of them are the cell underfoot, two are how the litter
// on it lies, one is the time of year and one is the creature's own
// account read against the price of a child.
//
// Every reading is divided by a full cell of its own field and held
// inside -1 to 1, which is the arithmetic the moisture and food slopes
// have used since a creature first read anything: a controller's
// weights are all the same size, so a channel arriving ten times the
// size of its neighbours is a channel shouting over them for no reason
// anybody chose.
func (h *Head) ground() {
h.row[Steady] = 1
v := h.Here
if v == nil || h.lit == nil {
return
}
b, c := h.Self, h.Self.Cell()
food, wet := h.Sense.Scale.Food, h.Sense.Scale.Wet
bed := v.Valley.Bed
_, warm, _ := v.Valley.Climate.Read(terra.Angle(v.Valley.Now))
slope := beast.Slope(c, h.lit)
if h.Sense.Loud {
h.row[Tissue], h.row[Damp], h.row[Lying] = v.Mass(c), bed.Moisture(c), h.lit(c)
h.row[LyingX], h.row[LyingY] = slope.X, slope.Y
h.row[Warmth], h.row[Spare] = warm, b.Store
return
}
over := slope.Over(food)
h.row[Tissue] = share(v.Mass(c), food)
h.row[Damp] = share(bed.Moisture(c), wet)
h.row[Lying] = share(h.lit(c), food)
h.row[LyingX], h.row[LyingY] = over.X, over.Y
h.row[Warmth] = beast.Clamp(2*warm - 1)
h.row[Spare] = share(b.Store, Costs(*b.Kind))
}
// share is one reading against one stated full cell, held inside -1 to
// 1. A full cell of nothing is a field this valley does not have, and
// the answer there is nothing rather than an infinity.
func share(x, full float64) float64 {
if full <= 0 {
return 0
}
return beast.Clamp(x / full)
}
// Watch hands one reading of the world to every graph-driven creature
// on a list, exactly as package beast's own does for the three-row
// ones. Anything driven by something else is left alone, so a valley
// holding both kinds is two calls and no branches.
func Watch(herd []*beast.Beast, v *beast.View) {
lit := func(c sim.Coord) float64 { return v.Valley.Bed.Litter(c).Mass }
for _, b := range herd {
if h, ok := b.Mind.(*Head); ok {
h.Here, h.lit = v, lit
}
}
}
The litter reading is handed over as a function and not as a number, because
beast.Slope asks for four cells and does not care where they come from. One
of those closures is made per phase and given to every creature in it, so a valley of
three thousand animals builds one a tick and not three thousand.
$ go run ./cmd/ears -mode row | head -32
ears: one creature's thirty-two numbers, tick 8101, summer of year 3
creature 48, standing on cell 14,9, store 249.5975 of 400.0000
a full cell of moisture is 1.2500, a bellyful is 100.0000 grams,
and a child of this creature costs 360.0000 energy units
the twenty-four the body fills in, in the order it fills them
slot what it is in the row
0 ray 0, how far it went 0.0625
1 ray 0, what it met 1.0000
2 ray 1, how far it went 0.0625
3 ray 1, what it met 1.0000
4 ray 2, how far it went 0.0833
5 ray 2, what it met -1.0000
6 ray 3, how far it went 0.0625
7 ray 3, what it met -1.0000
8 ray 4, how far it went 0.0625
9 ray 4, what it met -1.0000
10 ray 5, how far it went 0.0625
11 ray 5, what it met -1.0000
12 ray 6, how far it went 0.0833
13 ray 6, what it met -1.0000
14 ray 7, how far it went 0.0625
15 ray 7, what it met 0.2500
16 ray 8, how far it went 0.0625
17 ray 8, what it met 0.2500
18 the moisture slope east 0.0000
19 and going south 0.0000
20 the tissue slope east 0.0000
21 and going south -0.3083
22 the store, against Full 0.6240
23 the speed, against Top 0.0000
Nothing in that block is new. It is the row the wiring chapters settled, printed so the two halves can be read against each other: eighteen numbers of fan, four of gradient, two the creature took off itself, every one between −1 and 1.
$ go run ./cmd/ears -mode row | tail -22
the eight the ground fills in, and the arithmetic that put them there
slot what it is off the world in the row divided by
24 a constant 1.00 1.0000 1.0000 nothing, it is a constant
25 tissue underfoot 0.0000 0.0000 a bellyful, 100.0 g
26 moisture underfoot 1.2073 0.9659 a full cell, 1.25
27 litter underfoot 0.0928 0.0009 a bellyful, 100.0 g
28 litter slope east -0.0215 -0.0004 half a bellyful, 50.0 g
29 litter slope south 0.0101 0.0002 half a bellyful, 50.0 g
30 warmth 0.8542 0.7083 nothing: doubled, then 1 taken off
31 store against a birth 249.5975 0.6933 the price of a child, 360.0
what this creature's wiring is joined to
24 a constant 1.00 0 links
25 tissue underfoot 0 links
26 moisture underfoot 0 links
27 litter underfoot 0 links
28 litter slope east 0 links
29 litter slope south 0 links
30 warmth 0 links
31 store against a birth 1 links
channels it is charged for 1, so its Basal is 0.004020 and not 0.004000
Read the middle column against the right one. Moisture came off the bed at 1.2073 and went into the row at 0.9659, because a full cell of this valley's ground holds 1.2500. The store came off the creature at 249.5975 and went in at 0.6933, because a child of this particular animal costs 360.0000 energy units and 249.5975 is that share of it: a creature reading 1.00 on channel 31 can pay for a child on this tick. Warmth is the odd one out. The calendar hands over a number between nothing and one, so it is doubled and one is taken off, which puts the coldest week of the year at −1 and the hottest at 1 for the price of a multiply and a subtract.
Two of the thirty-two are now the same quantity divided by two different things, and that is deliberate. Slot 22 is the store against a full store, which is the number an animal needs to decide whether to go and eat. Channel 31 is the store against the price of a child, which is the number it needs to decide whether it is about to become a parent. A creature with a big body and a cheap child reads those two very differently, and only one of them is a fact about hunger.
The last two blocks are the rest of the chapter arriving early. This creature is joined to exactly one of the eight, channel 31, and it is paying for it: its Basal factor reads 0.004020 where a deaf animal off the same genome sits at 0.004000. Nothing else about the body moved.
Dividing eight numbers by a full cell looks like tidiness, so the flag below keeps the untidy version runnable: the eight written straight out of the world, litter in grams, moisture in the ground's units, the store in energy units, warmth left running from nothing to one.
// internal/gene/sense.go — inside type Sense struct
// Loud is the eight written down as they come off the world, in
// grams and moisture units and energy units, with nothing scaled
// and nothing clamped. It is kept behind a flag so what an unscaled
// input does to a controller can be run instead of described, and
// it is false in every valley this book ships.
Loud bool
It does nothing whatever to a founding population, because a founder is joined to none of the eight and an unread channel cannot be read wrong. The first creature to grow one link is where the bill lands. The block below takes a real animal out of a real valley, joins one link from channel 31 to the act that animal wanted least, and runs its own controller against its own reading twice.
$ go run ./cmd/ears -mode pair
ears: one link out of channel 31, under a scaled row and a raw one
creature 36 on cell 10,8, store 308.5175, a child of it costs 334.5245
channel 31 scaled 0.9223, which is the store over the price of a child
channel 31 raw 308.5175, which is the store
the link node 31 to node 33, which is walk, at weight 1.00
act scaled raw
rest 0.5104517782 0.5104517782
walk 0.2314139770 307.8266320207
sprint 0.2152600930 0.2152600930
turn left -0.6689922468 -0.6689922468
turn right -0.1290063122 -0.1290063122
bite 0.7789903062 0.7789903062
the act ranked first bite under the scaled row, walk under the raw one
Five of the six scores are identical to the last bit, because five of the six outputs have no link from channel 31. The sixth moves from 0.2314 to 307.8266. One weight of 1.00 multiplied by one number of 308.5175 buried every other link arriving at that output, and the creature that wanted to bite now wants to walk, and will want to walk on every tick until its store runs out.
The reasoning from symptom to cause is short. A controller is a sum of products and has no way of knowing that one of its inputs is kept in different units from the others. The weight that would make 308 a reasonable contribution here is about 0.003; the mutation pass moves a weight by up to 0.40 at a time and cannot land on 0.003 in any useful number of births. So a link that arrives at 1.00 on an unscaled channel is a link that decides everything from the tick it appears, and no amount of selection afterwards can quietly turn it down. Here is what one of them did to a valley.
$ go run ./cmd/ears -mode loud -years 16 | head -23
ears: 16x12 valley, tick 901, year 1 summer, 90 plants standing at 4654.1 grams
25 creatures founded on stream 12, deaf to all eight channels
the ground speaks: yes. an organ is charged for: yes. the row is scaled: no
one channel costs a creature's Basal factor times 1.005, for life
year alive born joined of those split ears Basal
2 11 15 1 1 0 0.091 0.003939
3 11 36 1 1 0 0.000 0.003883
4 7 52 1 1 4 0.000 0.003802
5 7 56 1 1 4 0.000 0.003692
9 0 72 1 1 4 0.000 0.000000
13 0 72 1 1 4 0.000 0.000000
17 0 72 1 1 4 0.000 0.000000
25 founded, 72 born, 97 struck off, 0 still walking after 57150 ticks
214 creatures were asked for a child: 72 made one, 39 could not pay for it
1 links were added and 1 of them came out of a channel with a bill on it
4 nodes were put in, and the counter handed out 205 numbers
every birth that opened a channel its line had never read
child tick gen parent mate the channel it opened link onto
26 1504 1 2 23 store against a birth 230 34
One link was ever added to a chargeable channel in that run, on tick 1,504, and the population never came back: twenty-five founded, seventy-two born, nothing alive by the ninth year. This is one seed and the extinction belongs to that seed and not to a law; a valley holding eleven animals is small enough that one of them behaving strangely can take the rest with it. The arithmetic in the block above is the part that generalises, and it is the reason every one of the eight is divided by a full cell before anybody sees it.
Cutting the eight channels out
Cutting the eight columns out of a founding wiring is a handful of lines and one idea. The links are cut and cut rather than left out: their numbers were minted before the cut, and a counter that only ever goes up does not hand them out again. A lineage that grows a link out of channel 27 three thousand ticks later is given a fresh number for it, and two lineages that grow it on two different ticks are given two, which is this world's standing answer about two separate arrivals at one wiring.
// internal/gene/sense.go
// Shut takes the eight latent columns out of a founding wiring: every
// link leaving a channel the body does not fill in is cut, and the
// count of them is handed back.
//
// This is the decision the whole chapter turns on. While the eight
// carried nothing, a link out of one of them multiplied zero by a
// weight and added zero to a total, so being wired to them was free and
// meant nothing. The moment they carry readings it is neither: a link
// out of channel 27 is an animal that knows what is lying on the ground
// under it, and an animal that knows that has an organ to keep alive.
// A founding lineage therefore opens with those columns cut, and
// hearing is something a lineage grows.
//
// The links are cut and not left out, because the numbers on them were
// minted before the cut and the counter never goes backwards. A lineage
// that later grows a link out of channel 27 is handed a new number for
// it, and two lineages that grow it a thousand ticks apart are handed
// two, which is what this world says about two arrivals at one wiring.
func Shut(g *Genome) int {
w := g.Wire
if w == nil {
return 0
}
cut := 0
for i := len(w.Links) - 1; i >= 0; i-- {
if w.Links[i].From >= beast.Inputs {
w.Cut(i)
cut++
}
}
return cut
}
// Root is one founding creature's genome in a valley whose ground
// speaks: the opening graph with its numbers off the generator handed
// in, and its eight latent columns cut out of it.
//
// Every number is drawn before anything is cut, so a founding
// population reads exactly the numbers off stream 14 it always read and
// throws forty-eight of them away. Drawing what is about to be
// discarded looks wasteful and is the same discipline every other draw
// in this volume is under: a count of numbers that depends on what the
// numbers are used for is a count no run can reproduce.
func Root(r *rand.Rand, m *Mint) *Genome {
g := Sprout(r, m)
Shut(g)
return g
}
$ go run ./cmd/ears -mode open
ears: the wiring a founding lineage opens with
the opening graph 192 links, every one of 32 inputs joined to every one of 6 outputs
the eight columns cut 48 links taken out, 8 channels by 6 outputs
what a founder is left 144 links, 6 biases, 0 hidden nodes
pairs a link may join 192, of which 48 are open
of those open pairs 42 lead out of a channel with a bill on it, 6 out of the constant
numbers minted 192, from 38 up
the genome, block by block
block wired to 32 wired to 24
BODY 10 10
MIND 198 150
TEMPER 3 3
LOOK 4 4
in all 215 167
a birth 653 509
what a founder reads, channel by channel
24 a constant 1.00 0 links out of it
25 tissue underfoot 0 links out of it
26 moisture underfoot 0 links out of it
27 litter underfoot 0 links out of it
28 litter slope east 0 links out of it
29 litter slope south 0 links out of it
30 warmth 0 links out of it
31 store against a birth 0 links out of it
channels it is charged for 0
its Basal factor 1.000000
Every number is drawn before anything is cut, which looks wasteful and is the discipline the whole volume runs on. The founding draws forty-eight numbers off stream 14 and throws them away, so a founding population reads exactly the numbers off that stream it has always read. A count of draws that depended on what the draws were going to be used for would be a count no run could reproduce.
The genome table is the price of the cut. A founder's MIND block holds 150 numbers instead of 198 and its whole genome 167 instead of 215, so a birth of one costs 509 numbers instead of 653. The line above them is the one to keep: 192 legal pairs, 48 of them open, and 42 of those 48 leading out of a channel that carries a bill.
Charging for a channel needs one question settled: what it means for a controller to read one. The answer here is the plainest available. A link is the only thing in a graph that carries a number out of a node, so a channel with no link leaving it cannot reach a total, a squash or an output, however much else the graph holds. One link out of a channel is reading it. Six links out of the same channel is still reading it once, because the organ was already built and a second nerve off it costs nothing to keep.
Two other tests were available and both are worse. Counting a link only when its weight is past some size sounds more honest, since a link at a weight of nothing carries nothing; it also means the bill moves every time the mutation pass nudges a weight, so a creature could be charged for an organ on Tuesday and not on Wednesday, and the size would be a number nobody could defend. Counting a link only when something downstream of it reaches an output is exactly right, and it costs a walk of the whole wiring at every birth to catch a case these operators almost never make: a link is only added to a pair that is legal, and a split replaces one link with two going the same way, so the only route to a nerve that arrives nowhere is a crossing that drops a hidden node's last way out. The link test is the cheap one, and on the wirings this valley actually builds it gives the same answer.
// internal/gene/sense.go
// Heard is which of the seven chargeable channels a wiring reads. A
// channel is read when some link in the graph comes out of it, and that
// is the whole test: a link is what carries a number from a node into
// an arithmetic, so a channel with no link leaving it is a channel
// nothing in the controller can ever see.
func Heard(g *mind.Graph) [Organs]bool {
var on [Organs]bool
if g == nil {
return on
}
for _, l := range g.Links {
if l.From >= Tissue && l.From < Wide {
on[l.From-Tissue] = true
}
}
return on
}
// Ears is how many of the seven a wiring reads.
func Ears(g *mind.Graph) int {
n := 0
for _, on := range Heard(g) {
if on {
n++
}
}
return n
}
// Toll is what those ears do to a body's Basal factor: one Upkeep on
// top for each of them, and nothing at all for a controller wired to
// none.
func Toll(g *mind.Graph) float64 { return 1 + Upkeep*float64(Ears(g)) }
// toll is the same number as the pool would charge it, which is nothing
// at all in a valley whose ground is silent or whose organs are free.
func (s Sense) toll(g *mind.Graph) float64 {
if !s.On || s.Free {
return 1
}
return Toll(g)
}
// internal/gene/birth.go — inside Pool.Breed
// The upkeep of whatever the child's wiring listens to, on top
// of the Basal factor its genome asked for. It is charged here
// and not in package beast, because a bill for an organ is a
// fact about a genome and beast.Kind has never heard of one.
row := kid.Stamp(beast.Fauna[0])
row.Basal *= p.Sense.toll(kid.Wire)
$ go run ./cmd/ears -mode bill
ears: what a channel costs the animal that reads it
the founding row Bulk 40.0 g, Basal 0.004000, Full 400.0, Convert 4.0
one bite 0.2500 g, worth 1.0000 energy units inside
one channel the Basal factor times 1.005
channels with a bill 7 of the 8
channels factor Basal a tick a full store a year
0 1.000 0.004000 0.160000 2500.0 576.0000
1 1.005 0.004020 0.160800 2487.6 578.8800
2 1.010 0.004040 0.161600 2475.2 581.7600
3 1.015 0.004060 0.162400 2463.1 584.6400
4 1.020 0.004080 0.163200 2451.0 587.5200
5 1.025 0.004100 0.164000 2439.0 590.4000
6 1.030 0.004120 0.164800 2427.2 593.2800
7 1.035 0.004140 0.165600 2415.5 596.1600
eight creatures of one genome, full stores, nothing to eat, ticked until they stop
channels Basal the tick against a deaf one
0 0.004000 2500 0
1 0.004020 2488 -12
2 0.004040 2476 -24
3 0.004060 2464 -36
4 0.004080 2451 -49
5 0.004100 2440 -60
6 0.004120 2428 -72
7 0.004140 2416 -84
reading all 7 costs 0.0056 energy units a tick more than reading none,
which is 20.1600 a year, or 5.0400 grams of standing tissue at Convert 4.0,
and it takes 84.5 ticks off what a full store covers
The bill lands where the child's row is stamped and nowhere else, which keeps two things
true. Package beast still knows nothing about channels, organs or graphs: a
Kind is ten numbers and one of them was multiplied on the way past. And the
price of a birth did not move, because that price is built out of Bulk, Convert and Full
and Basal is not in it. An organ costs its owner upkeep on every tick it is alive; it
costs nothing to have a child.
The second table is the arithmetic run instead of asserted. Eight creatures off one genome, full stores, nothing whatever to eat, ticked until each one stops: the deaf one lasts 2,500 ticks and the one wired to all seven lasts 2,416. Eighty-four ticks is about eight seconds of a valley running at ten ticks a second. Over a year the same bill comes to 20.16 energy units, which is 5.04 grams of standing tissue that a hearing animal has to find and a deaf one does not.
Four tests pin the parts of that a valley cannot show: that the opening graph did not move and a founder is joined to none of the eight; that a channel is charged once however many links read it, that the constant channel is never charged and that cutting the links takes the bill off again; that the eight stand at nothing while the switch is off, on a cell with plenty to say about itself; and that a cell carrying five bellyfuls of litter still hands over a number inside −1 to 1.
$ go test -count=1 ./internal/gene/ -run 'AFoundingWiring|AnOrganNothing|TheGroundIsSilent|EveryGroundChannel' -v
=== RUN TestAFoundingWiringIsDeafToAllEight
--- PASS: TestAFoundingWiringIsDeafToAllEight (0.00s)
=== RUN TestAnOrganNothingIsWiredToCostsNothing
--- PASS: TestAnOrganNothingIsWiredToCostsNothing (0.00s)
=== RUN TestTheGroundIsSilentUntilItIsSwitchedOn
--- PASS: TestTheGroundIsSilentUntilItIsSwitchedOn (0.00s)
=== RUN TestEveryGroundChannelLandsInsideMinusOneToOne
--- PASS: TestEveryGroundChannelLandsInsideMinusOneToOne (0.00s)
PASS
ok theworld/internal/gene 0.004s
Two pieces of arithmetic run this page and both can be done on paper. One turns a reading into a channel. The other turns a channel into a bill.
Scaling. A reading is divided by a stated full cell of its own field and then held inside −1 to 1. This valley's full cell of moisture is 1.25, so a cell holding 1.2073 goes in at 1.2073 ÷ 1.25 = 0.9659, which is the number the run above prints. A bellyful is 400 ÷ 4.0 = 100 grams, so 25 grams of litter goes in at 0.25 and 500 grams goes in at 5.00, which the clamp cuts back to 1.00. Everything past a full cell reads the same, and that is the trade: a creature cannot tell four bellyfuls from five, and it can tell a quarter of one from a half.
Slopes. A gradient is the cell east minus the cell west, halved because those two samples sit two cells apart. A reading running from nothing to full can change by at most one full cell across that pair, so the steepest slope this arithmetic can produce is half a full cell, and dividing by half a full cell is the whole of the scaling. Litter at 30 grams east and 10 grams west gives (30 − 10) ÷ 2 = 10 grams a cell, and 10 ÷ 50 = 0.20.
Warmth. The calendar hands out a number between 0 and 1 off one oscillator. Double it and take one off: 0 becomes −1, 0.5 becomes 0, 1 becomes 1. The 0.8542 in the run becomes 2 × 0.8542 − 1 = 0.7084, and the row reads 0.7083 because the warmth the row used carries more digits than the four the table prints.
The bill. A body's upkeep is one number times another: Bulk grams times Basal energy units a gram a tick. The founding row is 40 × 0.004 = 0.16 energy units a tick. Every channel a wiring reads adds 0.005 to a multiplier that starts at 1, so seven of them multiply Basal by 1 + 0.005 × 7 = 1.035, giving 0.00414, and the bill becomes 40 × 0.00414 = 0.1656. The seven halves of a percent are added and not compounded, because adding is the version a reader can do in their head and the difference between the two at these sizes is in the fifth decimal place. Over a full store of 400 the deaf animal covers 400 ÷ 0.16 = 2,500 ticks and the seven-eared one covers 400 ÷ 0.1656 = 2,415.5, and the run prints 2,500 and 2,416 because a tick is a whole number.
Write e for how many chargeable channels a wiring reads. Then
Basal(e) = Basal × (1 + u × e), and
bill(e) = Bulk × Basal(e), with u = 0.005
so the whole cost of hearing everything, over a year of 3,600 ticks, is
3600 × Bulk × Basal × u × 7 = 20.16 energy units,
which is 20.16 ÷ 4.0 = 5.04 grams of tissue. That is the number the valley is
being asked to decide about, and it is a small one.
The 16-year sensor run
Wiring it into a running valley is two decisions. The pool carries the switch and hands it to every driver it makes, so a valley cannot end up speaking to half its animals; and a founding creature is stamped through the same bill its children will pay, which for a founder comes to nothing at all, because a founder reads nothing.
// internal/gene/birth.go — inside Pool.Breed
c := row.Spawn(at, v.Now)
c.Store = row.Full * Opening
if kid.Wire != nil {
NewHead(kid, c).Sense = p.Sense
} else {
beast.NewWits(kid.Net(), c)
}
// cmd/ears/herd.go — founding a population that can hear
g := gene.Root(brains, p.Names)
row := g.Stamp(beast.Fauna[0])
row.Basal *= gene.Toll(g.Wire)
b := row.Spawn(beast.Centre(c), v.Now)
b.Store = 200
gene.NewHead(g, b).Sense = p.Sense
r.Add(b)
p.Stand(b, g)
Before the valley, one lineage on its own: two thousand births, four numbers off stream 19 in every one of them, and a line printed whenever a birth opened a channel that line had never read.
$ go run ./cmd/ears -mode grow
ears: one lineage, 2000 births, four numbers off stream 19 in every one of them
it opens with 38 nodes, 144 links and 192 legal pairs, 48 of them open
and it is deaf to all 7 channels the ground would tell it
every birth that opened a channel this line had never read
birth channel what it was given ears Basal x
4 31 store against a birth to 34 1 1.005
273 30 warmth to 35 2 1.010
383 28 litter slope east to 36 3 1.015
388 26 moisture underfoot to 36 4 1.020
after 2000 births of one line
hidden nodes 32
links 247
channels it reads 4 of 7
its Basal factor 1.020000
the whole genome 302 numbers
numbers the counter handed out 359
Four channels in two thousand births, at births 4, 273, 383 and 388, and then nothing for sixteen hundred more. The falling-off is arithmetic. The operator names its pair by index into the list of every legal pair, and that list grows as the graph does: at the founding, 42 of the 192 pairs lead out of a channel with a bill on it, which is better than one in five. This lineage finished on 32 hidden nodes, and a graph with 32 hidden nodes has about 2,400 legal pairs, of which the three channels it never opened account for 114. Growing a sense is easiest in a lineage that has not grown much else.
Now sixteen years of a valley. Sixteen by twelve cells with the rim cracked and the room rule on, twenty-five animals founded on stream 12 and every one of them deaf, one link in twenty and one node in fifty at every birth, and every child billed for what it can hear.
$ go run ./cmd/ears -mode herd -years 16
ears: 16x12 valley, tick 901, year 1 summer, 90 plants standing at 4654.1 grams
25 creatures founded on stream 12, deaf to all eight channels
the ground speaks: yes. an organ is charged for: yes. the row is scaled: yes
one channel costs a creature's Basal factor times 1.005, for life
year alive born joined of those split ears Basal
2 9 14 1 1 0 0.111 0.004061
3 8 32 1 1 4 0.250 0.004306
4 19 53 7 6 24 0.158 0.004460
5 15 74 16 14 40 0.200 0.004771
9 167 546 406 364 666 0.934 0.004210
13 317 922 938 807 1562 0.987 0.004205
17 346 1043 1001 864 1668 0.997 0.004187
25 founded, 1043 born, 722 struck off, 346 still walking after 57150 ticks
82371 creatures were asked for a child: 1043 made one, 9358 could not pay for it
1001 links were added and 864 of them came out of a channel with a bill on it
1668 nodes were put in, and the counter handed out 6193 numbers
every birth that opened a channel its line had never read
child tick gen parent mate the channel it opened link onto
26 1504 1 2 23 store against a birth 230 34
94 13550 8 88 55 tissue underfoot 350 37
305 24106 19 291 268 store against a birth 821 34
696 32093 26 425 519 litter slope south 3961 34
773 34525 38 770 718 litter slope east 4670 34
859 37760 22 450 360 store against a birth 5152 35
births that opened a channel their line had never read 6
births whose child did not inherit a parent's channel 86
the 346 creatures walking about at the end, by channels read
deaf, as every founder was 12
one channel 323
2 channels 11
and which channels they are listening to
25 tissue underfoot 334
26 moisture underfoot 0
27 litter underfoot 0
28 litter slope east 0
29 litter slope south 1
30 warmth 0
31 store against a birth 10
what they asked for, as a share of the passes they spent
act 12 deaf 334 hearing
rest 0.0464 0.0866
walk 0.0016 0.0324
sprint 0.0001 0.1090
turn left 0.0000 0.0001
turn right 0.0000 0.0003
bite 0.9519 0.7717
57150 ticks in 26.165s, 2184 ticks a second (measured here; yours will differ)
Start with the numbers that are only bookkeeping. A thousand and forty-three births over fifty-seven thousand ticks, a thousand and one links added, and 864 of those links came out of a chargeable channel — which is 86 percent of them, and follows from when 42 of the 48 open pairs are sensory. But only six of those births opened a channel their line had never read. The other 858 landed on a channel the lineage was already joined to, adding a second or a third nerve off an organ it had already built, which changes what the creature can do with the reading and changes its bill by nothing at all. (Twenty-six seconds of a Ryzen 7 3700X bought all of that. The tick count on the last line replays anywhere; the seconds and the rate beside it are this desk.)
The six are the finding, and the second of them is the one that matters. Creature 94, born on tick 13,550, eight generations out of a founder, out of parents 88 and 55: it was given link number 350, running from node 25, the tissue standing on the cell it is on, to node 37, which is the bite. Not one of its ancestors held that link or any other out of channel 25. It could tell there was food under its feet, and it was joined straight to the mouth.
Look at where that ended. Of the 346 animals walking at the close of year seventeen, 334 are reading channel 25 and twelve are still deaf, and the mean number of channels read across the whole population is 0.997. Ten are reading the store channel, one the litter slope going south, and nobody at all is reading moisture, litter mass, the slope going east or the season. One connection, made once, on one tick, in one animal, is now in almost every animal alive.
Hearing can also be lost, and the run counts that too: 86 births produced a child that did not inherit a channel one of its parents was reading. Nothing deletes a link in this world, so those are all crossings. A child's wiring is the links both parents carry plus the ones only the other parent carries, so a link the parent of record holds alone is a link the child does not get, and if that was the last nerve off a channel the child is deaf to it and its Basal factor drops back. A nerve onto a sensory channel arrives on about one ask in ninety-five; losing one is what happens when two lineages that grew apart make a child.
Be clear about what a sweep like that is and is not evidence for. Creature 94 was one animal among a few dozen alive at the time, and the reason its descendants are almost the whole valley eight years later is partly that its line kept feeding itself and partly that the valley is small and lineages in it die wholesale. One connection reaching almost everybody is what this population does with any advantage and with plenty of things that are not advantages at all.
Read the last table slowly and not too far. The twelve deaf survivors asked for the bite on 95 percent of the passes they spent and asked for nothing else worth counting; the 334 hearing ones asked for it 77 percent of the time and asked to sprint on 11 percent. Those are two different lineages with two different histories, and the table says what they did, not what the channel made them do.
Then run the same valley with the bill switched off, so that an organ is free.
$ go run ./cmd/ears -mode herd -years 16 -bill=false | tail -30
1714 52433 33 1464 1479 litter slope south 3971 34
1716 52434 37 1681 1427 litter slope east 3974 33
1759 53365 40 1605 1515 litter slope south 4102 36
births that opened a channel their line had never read 20
births whose child did not inherit a parent's channel 67
the 355 creatures walking about at the end, by channels read
deaf, as every founder was 344
one channel 11
and which channels they are listening to
25 tissue underfoot 3
26 moisture underfoot 1
27 litter underfoot 1
28 litter slope east 2
29 litter slope south 4
30 warmth 0
31 store against a birth 0
what they asked for, as a share of the passes they spent
act 344 deaf 11 hearing
rest 0.0705 0.0617
walk 0.0498 0.0013
sprint 0.0364 0.0414
turn left 0.0009 0.0499
turn right 0.0117 0.0197
bite 0.8306 0.8258
57150 ticks in 21.432s, 2667 ticks a second (measured here; yours will differ)
Twenty births opened a channel their line had never read, against six, and at the end of it eleven of 355 animals can hear anything and 344 are deaf. The free valley grew more senses and kept fewer. That is the opposite of the story a surcharge is supposed to tell, and the honest reading of the pair is that the bill did not decide either outcome. Half a percent on Basal is 5.04 grams of tissue a year against a valley where the difference between a good year and a bad one is thousands, and where a single lineage taking most of the roster is an ordinary Tuesday. The two runs are two histories of one seed that part company on tick 1,504, and in one of them tissue-underfoot-to-bite turned up in an animal that went on to breed.
That is a real result and it is the one the run supports. The bill is not the mechanism that picked channel 25; it is the standing charge that makes picking anything a decision with a price on it, and the price is small enough that a valley of a few hundred animals over sixteen years cannot separate it from luck. Sixteen years is the measurement this page can afford. A page that quoted the billed run alone and said the surcharge shaped the outcome would be reading one sample as a law.
Figure 65.1 — a founder is joined to the twenty-four its body fills in; every link out of the other eight is one a lineage grew, and one it pays for.
Why sensors pay rent
The general form of this page is older than any of its code. A sense is not free, and an animal that is charged for one will only keep it if the thing it hears is worth more than the keeping. Cave fish lose their eyes. That is the whole mechanism, and putting it into a simulated world takes three parts, none of which is the network.
The channel has to exist before anybody wants it. A link is named by the pair of nodes it joins, so a node added to the input side after the fact would match nothing that came before it and every genome already alive would be describing a different row. The eight are in the first graph this world ever built, which is why the wiring can be grown towards them at all. What a lineage grows is never a new input. It is a connection to an input that was always there and never listened to.
The reading has to arrive in the same units as its neighbours. Weights come out of one span and mutate in steps of one size, so a controller has no way to discover that one of its inputs is a hundred times the others. Dividing every channel by a stated full cell is what makes a weight of 1.00 a sensible opening for any of them, and the failure above is what one unscaled channel does to a decision the first time a link reaches it.
The bill has to be charged against what the animal already spends. Basal is the number every tick of every life multiplies, so half a percent on it is a charge no creature can dodge by resting, hiding or being lucky with weather. It also stays out of the birth price, so hearing makes a creature more expensive to run and no more expensive to make, which is the right distinction: an organ is a running cost.
What this page cannot show is the fourth part, and it is fair to say so plainly. A surcharge only becomes selection when the population is large enough, or the run long enough, for a difference of five grams a year to separate from the noise of who happened to be standing next to a plant. Sixteen years of a few hundred animals is not that. The bill is built, it is exact, it is measurable on a fasting animal to the tick, and whether the valley can feel it is a question of scale rather than of design.
- You can name the eight channels in order, say which one carries no bill, and give the reason a constant is not a sense.
- Handed a cell holding 25 grams of litter and a creature whose store fills at 400 energy units at Convert 4.0, You can work out what channel 27 hands the controller, and say what a cell holding 500 grams hands it instead.
- You can say why a founding lineage opens on 144 links instead of 192, what that does to the pairs the add-link operator can join, and why the 48 cut links still used up 48 numbers.
- You can state the test for whether a wiring reads a channel, and explain why six links out of one channel cost exactly what one does.
- Given Bulk 40 and Basal 0.004, You can work out the upkeep, the ticks on a full store and the grams a year for a creature reading all seven, and check my answer against the fasting table.
- You can explain, in terms of weight sizes and the size of a mutation step, why one unscaled channel pins a controller to one action and why selection cannot quietly turn it down.
Exercise 1 — make the bill ten times as heavy. Half a percent
a channel is small enough that sixteen years of valley cannot see it. Predict what a
creature reading all seven loses when a channel costs five percent instead, then edit
Upkeep in internal/gene/sense.go to 0.05 and run
go run ./cmd/ears -mode bill.
Basal goes to 0.005400, the bill to 0.216000 a tick, and the fasting table drops from 2,500 ticks to 1,852: a loss of 648 ticks against 84, and 201.60 energy units a year against 20.16, which is 50.4 grams of tissue. A creature reading everything now has to find half a bellyful a year more than a deaf one.
Then think about what that would do to the page above rather than running it. A charge that size would be visible in a valley, and it would also be a charge nobody measured: the point of a small number here is that it is a bill and not a verdict. Turning it up until the valley obeys is the fitness function coming back in through a different window.
Exercise 2 — take the node operator away and watch senses arrive
faster. One birth in twenty adds a link and one in fifty puts in a node.
Predict what happens to the channels a lineage opens when only the first is running,
then edit Often in internal/gene/grow.go to
Growth{Link: 0.05} and run go run ./cmd/ears -mode grow.
The lineage opens all seven channels, at births 4, 273, 558, 560, 925, 1247 and 1922, and finishes on 160 links, no hidden nodes at all and a Basal factor of 1.035000. With both operators running it managed four of the seven over the same two thousand births.
The node operator is what makes growing a sense harder. Every split adds a node, and every node adds a row and a column to the list of pairs a link may join, so the forty-two sensory pairs become a smaller and smaller share of the list the draw indexes into. A lineage that is busy elaborating its middle is a lineage that has stopped listening to new things, and nothing anywhere decided that.
Exercise 3 — grow the same lineage off two other seeds. The
run on the page opened the store channel first, on birth 4. Predict whether that
ordering means anything, then run go run ./cmd/ears -mode grow -seed 7
and go run ./cmd/ears -mode grow -seed 11.
Seed 7 opens the store channel at birth 75, then litter, litter slope east, litter slope south, moisture, and tissue at birth 1,695: six of seven. Seed 11 opens litter at birth 19, then the store, tissue, moisture, litter slope east and warmth: six of seven again, in a different order. The first channel a line opens is the pair the draw named, and nothing else.
Two details in those runs matter. Both lineages end at six channels and not seven, for the same reason as the run on the page: the pair list grows. And some of the links land on node numbers in the hundreds, which are hidden nodes, so a lineage can grow an ear that feeds a middle stage of its own arithmetic rather than going straight at an action.
There are now animals in this valley carrying links that other animals in the same valley have never held, and the crossing that makes a child out of two of them lines those links up by the numbers they carry and hands the unmatched ones over whole from one side. That works when the two are close. Two lineages that have been apart for a hundred generations are a different question, and nothing anywhere in this valley yet asks whether two animals standing next to each other are still alike enough for a child of them to work at all.