What the lanterns are
Fourteen lanterns light the way to the cottage. Twelve are path lanterns: solar garden lights, 46.2 cm from the ground to the top of the head. Each is a round black stake 3.6 cm across, pushed 22 cm into the ground, with a square head on top: a plinth 14 cm square, four amber panes from 26 to 38 cm up in a bronze frame (corner posts, rails and a round-topped arch on each face), a hipped roof with eaves 19 cm square and a small black solar panel on its top block, and inside a small filament. They stand in six pairs along the last 16 m of the walkway before the cottage's steps: the first pair 1.8 m back from the steps, then a pair every 2.8 m, each lantern 1.5 m out from the walkway's middle, so each pair faces across the walkway. The other two are wall lanterns on the cottage's porch, one each side of the door: the same head at 0.7 of the size, its solar panel bronze like its roof, hung from a bronze bracket whose arm reaches 17 cm out from the wall.
By day the lanterns are dark. When the world's clock reaches dusk (17:28), every lamp fades up over a quarter of an hour of the world's day, which is 15 seconds of scene time, since the world's day lasts 24 minutes; at dawn (06:31) they fade out the same way. How bright a lit bulb looks follows the hour, because the camera's exposure opens up about 5000-fold as the evening darkens: about 2800 nits at dusk, falling to 1.3 nits from 20:00. Each lantern also throws real light: a deep gold pool on the grass and the walkway, reaching 5 m. Walk within 4 m of a lit path lantern and that lantern alone brightens to 1.45 times in 0.4 s; walk away and it dims back. The wall lanterns never brighten: they have no sense of who is near.
The listing
// ===== The world's lamp level: one value every lamp follows =====
field dayLength : duration = sim(24 min) // the world's day: its clock runs 60 times the scene's
field lampLevel : fraction = 0, within: 0 ..= 1, mutable: true
field lampColor : color = color(1, 0.397, 0.0953) // about 2700 K: the bulb's glow, the inner light
field glassColor: color = color(1, 0.3, 0.045) // deeper: the panes' and the bronze's glow
on(created, { // start: a world arriving at night is lit at once
let h = hour(now(world));
if h >= sky.duskHour || h < sky.dawnHour { set(lampLevel, 1); } else { set(lampLevel, 0); }
})
on(dusk, start(transition(lampLevel, to: 1, over: world(15 min), ease: linear, from: current, begin: dusk.due)))
on(dawn, start(transition(lampLevel, to: 0, over: world(15 min), ease: linear, from: current, begin: dawn.due)))
// ===== A bulb's brightness by the hour: world data =====
field bulbBrightness: curve = curve( // eight evening hours, log-linear between
points: [(16.975, 3600 nits), (17.475, 2800 nits), (17.725, 1600 nits), (17.975, 800 nits),
(18.475, 160 nits), (18.975, 24 nits), (19.475, 3 nits), (19.975, 1.3 nits)],
between: logarithmic)
fn eveningHour(h: number) number { // a morning hour mirrored about noon:
if h < 12 { 24 - h } else { h } // the sun stands as high at 7:00 as at 17:00
}
// ===== The lanterns' materials, held by the world, shared by all fourteen =====
part materials // a part with no frame: a holder
part lanternBlack: shiny(srgb(12, 13, 17), highlight: 0.9, shininess: 90) // the stakes
part lanternMetal: shiny(srgb(88, 62, 40), highlight: 0.22, shininess: 12) // the wall brackets
part lanternHead : [shiny(srgb(88, 62, 40), highlight: 0.22, shininess: 12),
litByLayers([world, interior]), // frame, roof, plinth
glowing(color: glassColor, strength: glow)]
field glow: nits = 0 nits // derived below: not mutable
part lanternGlass : [shiny(srgb(255, 205, 130), highlight: 0.45, shininess: 30),
translucent(covers: 0.12), // the panes and lining
glowing(color: glassColor, strength: glow)]
field glow: nits = 0 nits // derived below: not mutable
part lanternBulb : [plain(srgb(255, 214, 122)), // the filament
glowing(color: lampColor, strength: glow)]
field glow: nits = 0 nits // derived below: not mutable
derive(materials.lanternBulb.glow, lampLevel * bulbBrightness.at(eveningHour(hour(now(world)))))
derive(materials.lanternGlass.glow, materials.lanternBulb.glow * 0.09)
derive(materials.lanternHead.glow, materials.lanternBulb.glow * 0.0015)
// ===== The head both kinds share: a design, placed nowhere =====
part lanternHead
// its measurements at size 1: fixed and common, read by its shapes by name
field base : meters = 0.24 m, common: true // the plinth's underside, above the ground
field glassFoot : meters = 0.26 m, common: true // the glass's foot: the plinth's top
field glassTop : meters = 0.38 m, common: true // the glass's top: the eaves' underside
field eave : meters = 0.095 m, common: true // the eaves' half width: 19 cm square
field top : meters = 0.462 m, common: true // the head's top: the solar panel's face
field size : number = 1, within: 0.5 ..= 1 // own and fixed: feeds construction
field panel : ?shape = None // own: the mount's solar panel, or none
field panelIn : material = materials.lanternHead // own: what the panel is drawn in
field hangsAt : place = (0, 0, 0) // own: where the head sits on its mount
field nearGain : number = 1.45, within: 1 ..= 2, common: true // fixed: how much brighter when someone is near
field gain : number = 1, within: 1 ..= nearGain, mutable: true // own: how much brighter this one is drawn now
field cdPerNit : candelaPerNit = 0.45 candelaPerNit, within: 0 ..= 2, common: true // one value for the design and its copies
// its shapes: what varies (size) is passed; the measurements are read
fn tracery(size: number) shape { // the plinth, corner posts, rails and arches
let arc = fn(k: count) point {
(0.046 * cos(k * 22.5 deg), 0.326 + 0.046 * sin(k * 22.5 deg), 0.059)
};
let sidePieces = List[shape]() <- // one side's rails and arch, on the front (+z)
box(x: -0.052 ..= 0.052, y: 0.292 ..= 0.300, z: 0.056 ..= 0.062), // the low rail
box(x: -0.052 ..= 0.052, y: 0.371 ..= glassTop, z: 0.056 ..= 0.062), // the top rail
each u in [-0.030, 0.000, 0.030] yield // three mullions between the small panes
box(x: u + (-0.002 ..= 0.002), y: glassFoot ..= 0.292, z: 0.056 ..= 0.062),
box(x: -0.0025 ..= 0.0025, y: 0.300 ..= 0.371, z: 0.056 ..= 0.062), // the arch's mullion
bar(from: (-0.046, 0.300, 0.059), to: (-0.046, 0.326, 0.059), width: 0.006, thickness: 0.006), // its legs
bar(from: ( 0.046, 0.300, 0.059), to: ( 0.046, 0.326, 0.059), width: 0.006, thickness: 0.006),
each k in 0 ..< 8 yield // its half circle
bar(from: arc(k), to: arc(k + 1), width: 0.006, thickness: 0.006);
let side = join(sidePieces);
let pieces = List[shape]() <-
box(x: -0.07 ..= 0.07, y: base ..= glassFoot, z: -0.07 ..= 0.07), // the plinth, 14 cm square
each (sx, sz) in [(1, 1), (-1, 1), (1, -1), (-1, -1)] yield // four corner posts
box(x: sx * (0.052 ..= 0.062), y: glassFoot ..= glassTop, z: sz * (0.052 ..= 0.062)),
each f in 0 ..< 4 yield turn(side, by: f * 90 deg, about: up); // the side, four ways round
scale(join(pieces), by: size)
}
fn panes(size: number) shape { // four amber panes, a pressed floor and a ceiling
let pane = face(points: [(-0.054, glassFoot + 2 mm, 0.058), (0.054, glassFoot + 2 mm, 0.058),
(0.054, glassTop - 2 mm, 0.058), (-0.054, glassTop - 2 mm, 0.058)]); // facing front
let tip = (0.0125, 0.004, 0.0125); // one cell of the floor: 2.5 cm square, 4 mm high
let corners = [(0, 0, 0.025), (0.025, 0, 0.025), (0.025, 0, 0), (0, 0, 0)];
let pyramid = join(List[shape]() <-
each k in 0 ..< 4 yield face(points: [corners[k], corners[(k + 1) % 4], tip])); // four triangles
let pieces = List[shape]() <-
each f in 0 ..< 4 yield turn(pane, by: f * 90 deg, about: up),
each n in 0 ..< 16 yield // the floor: 4 by 4 pyramids, 1 mm over the plinth
move(pyramid, by: (-0.05 + 0.025 * floor(n / 4), glassFoot + 1 mm, -0.05 + 0.025 * (n % 4))),
face(points: [(-0.05, glassTop - 1 mm, -0.05), (0.05, glassTop - 1 mm, -0.05),
(0.05, glassTop - 1 mm, 0.05), (-0.05, glassTop - 1 mm, 0.05)]); // the ceiling, facing down
scale(join(pieces), by: size)
}
fn filament(size: number) shape { // two uprights, a bar across, a small hot coil
let pieces = join([
box(x: -0.0075 ..= -0.0045, y: 0.30 ..= 0.37, z: -0.0015 ..= 0.0015),
box(x: 0.0045 ..= 0.0075, y: 0.30 ..= 0.37, z: -0.0015 ..= 0.0015),
box(x: -0.0075 ..= 0.0075, y: 0.366 ..= 0.37, z: -0.0015 ..= 0.0015),
box(x: -0.0045 ..= 0.0045, y: 0.32 ..= 0.35, z: -0.0045 ..= 0.0045)]);
scale(pieces, by: size)
}
fn roof(size: number) shape { // a fascia, a hipped roof in two pitches, a top block
let eaves = glassTop + 8 mm; // the fascia's top
let hipped = loftAlong(profiles: [outline.rectangle(width: 2 * eave, height: 2 * eave),
outline.rectangle(width: 0.14, height: 0.14),
outline.rectangle(width: 0.104, height: 0.104)],
spine: spine.line(from: (0, eaves, 0), to: (0, eaves + 5 cm, 0)),
stations: [0, 0.28, 1], // shallow at the eaves, steeper to the block
caps: false); // open: it sits on the fascia
let pieces = join([
box(x: -eave ..= eave, y: glassTop ..= eaves, z: -eave ..= eave), // the fascia
hipped,
face(points: [(-0.052, eaves + 5 cm, 0.052), (0.052, eaves + 5 cm, 0.052),
(0.052, eaves + 5 cm, -0.052), (-0.052, eaves + 5 cm, -0.052)]), // the roof's top, facing up
box(x: -0.05 ..= 0.05, y: eaves + 5 cm ..= eaves + 7 cm, z: -0.05 ..= 0.05)]); // the top block
scale(pieces, by: size)
}
fn solarPlates(gap: meters) shape { // a panel on the top block, 4 mm thick, 8.4 cm square
let y = top - 4 mm ..= top;
if gap > 0 m { // two plates: the bronze block shows between
join([box(x: -0.042 ..= 0.042, y: y, z: -0.042 ..= -gap / 2),
box(x: -0.042 ..= 0.042, y: y, z: gap / 2 ..= 0.042)])
} else {
box(x: -0.042 ..= 0.042, y: y, z: -0.042 ..= 0.042) // one plate
}
}
part glass: panes(size), material: materials.lanternGlass, at: hangsAt
part bulb : filament(size), material: materials.lanternBulb, at: hangsAt, castsShadow: false
part cap : roof(size), material: materials.lanternHead, at: hangsAt
part plate: tracery(size), material: materials.lanternHead, at: hangsAt, castsShadow: false
if let Some(p) = panel {
part solar: scale(p, by: size), material: panelIn, at: hangsAt
}
part light: pointLight(color: color(1, 0.14, 0.01), source: 2 cm, reach: 5 m, castsShadow: true),
at: hangsAt + (0, 0.335 m * size, 0)
part inner: pointLight(color: lampColor, source: 2 cm, reach: 0.35 m, layers: [interior]),
at: hangsAt + (0, 0.335 m * size, 0)
derive(glass.tint, gain) // this lantern's two parts, not the materials
derive(bulb.tint, gain)
derive(light.intensity, materials.lanternBulb.glow * cdPerNit * gain)
derive(inner.intensity, materials.lanternBulb.glow * 0.006 candelaPerNit * gain)
// ===== The path lantern: the head on a stake, with nearness =====
part pathLantern: lanternHead(panel: Some(solarPlates(gap: 2 mm)), // two plates with a 2 mm gap,
panelIn: materials.lanternBlack) // in the stake's black
field near: bool = false, lives: client // each visitor's own; derived, so not mutable
fn stake() shape { // a round stake 3.6 cm across, 22 cm underground
lathe(profile: [(0, -0.22), (0.008, -0.20), (0.018, -0.12), (0.018, base + 4 mm), (0, base + 4 mm)],
steps: 14)
}
part post: stake(), material: materials.lanternBlack
area(self, sphere(radius: 4 m, at: (0, 0.2, 0)))
derive(near, occupied(post, by: me))
on(created, start(chase(gain, toward: if near && lampLevel > 0 { nearGain } else { 1 },
speed: rate(nearGain - 1, per: sim(0.4 s)))))
// ===== The twelve: six pairs along the walkway's last 16 m =====
part pathLanterns // a frameless holder: hide it, hide all twelve
each p in 0 ..< 6 {
each (k, side) in [(0, -1), (1, 1)] { // left, then right, of the walkway
let way = land.walkway;
let spot = way.spotAt(way.fromEnd(1.8 m + 2.8 m * p), across: side * 1.5 m); // a point on the ground
part lantern[2 * p + k]: pathLantern, at: spot
}
}
// ===== The wall lantern: a new design from the old =====
part wallLantern: lanternHead(size: 0.7, panel: Some(solarPlates(gap: 0 m)), // one plate, in the head's bronze
hangsAt: (0, -(top * 0.7) - 4 mm, 0.17), // 0.327 m under the bracket's top
cdPerNit: 1.2 candelaPerNit)
fn wallBracket() shape { // a plate on the wall and an arm 17 cm out
join([box(x: -0.04 ..= 0.04, y: -0.07 ..= 0.07, z: 0 ..= 0.015),
box(x: -0.015 ..= 0.015, y: -0.015 ..= 0.015, z: 0.015 ..= 0.17)])
}
part bracket: wallBracket(), material: materials.lanternMetal // full size: the bracket's own frame
The two wall lanterns hang on the cottage's porch, which the cottage's own text declares. They are written in a file of their own, each line declaring its lantern by a path through the cottage to the porch:
part cottage.porch.wallLantern1: wallLantern, at: (-0.7, 2.4, 0) part cottage.porch.wallLantern2: wallLantern, at: (0.85, 2.4, 0)
Walking through it
The world's lamp level
lampLevel is a field of the world, the root part (Parts): written outside any part, in a file that sits in the world's top folder, so that what it declares is the world's own (Parts: a file that adds to a part). It is a fraction, ranged 0 to 1 by within: 0 ..= 1, starting at 0, and mutable: true because rules change it. It belongs to the world and not to the lanterns because more than lanterns follow it: the five lit windows of the cottage glow from the same level. lampColor and glassColor are fixed fields: named colors the glows and the inner light use (Values: colors). dayLength is a world setting: a day of world time lasts 24 minutes of the scene's, so the world clock runs 60 times as fast (Values: the day length).
Two events and one start act move it:
on(dusk, ...)andon(dawn, ...)answer messages the world's day clock delivers (Events: triggers). Each starts atransitionanimator: built as a value, thenstarted (Actions). It moves the level in a straight line (ease: linear) from wherever it is (from: current) to 1 or 0 overworld(15 min), a quarter of an hour of the world's day: 15 seconds of the scene's clock on a 24-minute day, and still a quarter of the evening's hour if the day length changes (Values: clocks).begin: dusk.duestarts the fade at the moment dusk was due, which may already be past. A machine that reads the message late, or a visitor who arrives in the middle of the fade, is put that far into it, so every machine shows the same level (Animators: starting in the past). A dawn that comes during a dusk fade takes over from where the level has got to: one value, the newest motion taking over.on(created, ...)on the world is a start act (Loading): a world that arrives after dusk or before dawn starts with the lamps fully on, with no fade. The hours are the sky's answers,sky.duskHourandsky.dawnHour(17:28 and 6:31 on 15 October at 45 degrees north), so they are never typed twice (Sky and weather: dusk and dawn). It is in a braced acting block because it calculates (let h) before it acts, and Cone'sif ... elsechooses between twosets (Blocks: acting blocks, Control flow). Had it been part of building the lanterns, a warm start from cached products would have left the lamps dark at night. It runs before the world reads its firstduskordawn, so a dusk waiting in the first tick fades from the level it set (Loading: start comes before every message).
How bright a bulb is at an hour
The brightness is world data, not code. bulbBrightness is a fixed field of the world holding a curve: the eight evening hours and the bulb's radiance at each (3600 nits half an hour before dusk, 2800 at dusk, down to 1.3 at 19:58), blended on a log scale between them (between: logarithmic), so each step of the hour divides the brightness by the same factor, as the exposure multiplies. The curve holds at its ends: 3600 nits before the first hour, 1.3 after the last. Its points carry their unit, so bulbBrightness.at(h) is in nits. A morning hour is read as the evening hour mirrored about noon, where the sun stands at the same height: eveningHour, a two-line function, turns 7:00 into 17:00 and leaves an afternoon hour as it is. Its parameter is h, not hour, because a local may not hide a name its own block reads, and the block's caller reads the vocabulary's hour (Blocks: local names).
The materials and their glow
The five lantern materials are held by a frameless part at the world's root, materials, by convention, and named by path from every lantern (materials.lanternGlass). Each is a part holding a value of type material, declared part lanternGlass: [shiny(...), ...] (a list: a base material, then its modifiers), with an identity: every bulb, path or wall, is drawn in the one lanternBulb, so one change to its glow reaches all fourteen. Each glowing material says its glow's color and where its strength comes from with one modifier, glowing(color: ..., strength: glow): the bulb in the lamp's color, the glass and the bronze head in the deeper glassColor, each at the strength its own glow field holds (Materials: a glow). The bronze is two materials of one color only because the head's is lit on the interior light's layer too (litByLayers([world, interior])) and the bracket's, naming no layers, is on the built-in world layer alone, as the stakes and the ground are (Lights: light layers).
The three derive lines are subscriptions: the bulb glows at the lamp level times the hour's brightness; the glass at 0.09 of the bulb, so the interior reads amber; the bronze at 0.0015, "a faint warm lift, not a light". They subscribe to the clock through now(world): between 18:00 and 20:00 the bulbs dim from about 800 to 1.3 nits with no animator running, only a formula.
The head: a design with own and common fields
lanternHead has no at, so it is a design, a part placed nowhere. It is a design of its own because both kinds of lantern share it and differ in their mounts. Its fields:
base,glassFoot,glassTop,eaveandtopare the head's measurements at size 1: fixed andcommon: true, so the head's shapes read them by name and nothing passes them (Construction: what a shape reads). Each is written once; the roof's eaves sit 8 mm overglassTop, the stake's top 4 mm overbase.size,panel,panelInandhangsAtare own and fixed: each copy has its own value, given when it is made. They feed construction, so they never force a rebuild, and the twelve path lanterns, all passing size 1 to the same shapes, share one build of each.nearGainis fixed andcommon: true: a named number, 1.45, used three times, as the top ofgain'swithin:range, as the chase's goal and in its speed (Fields: named numbers).gainis own andmutable: true: every lantern brightens alone.cdPerNitiscommon: true: one value, held by the design, read by every copy: 0.45 candela of light for each nit of the bulb's glow. Its type is a unit,candelaPerNit, ranged 0 to 2 bywithin:(Values: a unit as a type).
The shapes are construction pipelines, each a function whose result is a shape, fn name(...) shape { ... }, written inside the head, a function of the head's size that reads the head's measurements by name, and called by the parts that draw them; every name in them is a tool from the Appendix: shape tools or one of the head's fields. tracery is the plinth, the corner posts and one side's rails, mullions and arch, made of boxes and bars, the arch's eight bars from a closure (Functions: closures); a mullion is 4 mm wide about its place, u + (-0.002 ..= 0.002), a range shifted by a number (Values: ranges); the side is turned four ways round with turn, and the whole scaled by size. panes is four flat faces, a floor pressed into 4 by 4 small pyramids (each four triangles, face of three points, moved into place) and a ceiling facing down; filament four small boxes; roof a fascia, a hipped roof lofted through three squares, open at both ends (caps: false), since the fascia closes it below (Sculpting: the roof by loftAlong), a flat face over its top, 2 mm wider each way than the block, and the top block. Each shape's pieces are gathered into a list, written out (join([a, b, c])) or built with Cone's collection form (List[shape]() <- box(...), each f in 0 ..< 4 yield turn(...)), and join(pieces) gives the joined shape; the shape's last line, scale(join(pieces), by: size) or scale(pieces, by: size), is its value (Blocks: joining shapes). The floor of pyramids is one loop over sixteen cells, the row floor(n / 4) and the column n % 4. Points mix plain numbers and lengths, (0.054, glassTop - 2 mm, 0.058): a plain number in a shape is meters (Values: plain numbers in shapes).
The head's panel is a shape, the solar panel on the top block, or None for none, and panelIn the material it is drawn in: each mount passes its own. The path lantern's is two plates with a 2 mm gap, through which the bronze block shows as one pale line, in the stakes' black; the wall lantern's is one plate in the head's bronze. Both are calls of the head's solarPlates, written in the copy's arguments, which are worked out inside the copy (Designs: a copy's values). The head draws whichever it is given at its own size, scale(p, by: size). A panel is a part of its own because a shape has one material. Each drawn part names one shape after the colon and one material with the material: option, and its place with at:. The bulb and the plate cast no shadow (castsShadow: false, an option of a drawn part): the bulb is the light, and the tracery's shadow thrown by a point light a few centimeters away was a hard sunburst on the ground.
The two lights are parts like any other: light, at the filament's middle (0.335 m up at size 1), a deep gold, a source 2 cm in radius, reaching 5 m and casting shadows (castsShadow: true, an argument of the light, Lights: shadows), on the built-in world layer since it names no other; inner, at the same point in the lamp's own color, reaching 35 cm on the interior layer, which only the head's bronze answers, so the frame reads lit from within without brightening the grass a meter away. Their strength is a subscription: the bulb's glow, in nits, times candela per nit, times the gain. Three effects (the evening's schedule, the hour, nearness) meet in one formula the author wrote (Subscriptions: several effects on one value). The tints multiply this lantern's glass and bulb by the gain, leaving the shared materials untouched; a tint given a number is the gray of that number, so the gain brightens every color alike (Materials: the tint).
The path lantern: a copy that adds
pathLantern: lanternHead(panel: ..., panelIn: ...) is a copy that gives its head a two-plate black panel and adds three things (Designs: a new design from an old): the stake (stake(), a function of the path lantern's own that makes a shape, one lathe call over a five-point outline in 14 steps, its top 4 mm over the head's base, Sculpting) with the space round it, a field near, and two rules. area(self, sphere(radius: 4 m, at: (0, 0.2, 0))), a call in the post's body, is a sensing area, registered once with the post: a ball of 4 m round a point 0.2 m up it, in the post's frame, so it moves with the lantern, written with the same sphere a shape would use (Physics: areas). occupied(post, by: me) turns the engine's coming-in and going-out into one value a formula can read, true while this machine's visitor is inside; so near, computed for each visitor, is lives: client, and each visitor sees the lantern by them brighten. The chase is the nearness: started when each copy is made and never stopped, it is "a value always following another" (Animators: two kinds of chase). It moves at a steady rate, rate(nearGain - 1, per: sim(0.4 s)) (0.45 per 0.4 s of simulation time), towards nearGain (1.45) while that visitor is near and the lamps are lit at all, else towards 1; a visitor who steps in for 0.2 s takes the gain only to about 1.22 before it turns back. toward: is a value block: the engine reads it again each tick and moves the chase's goal.
Because the rule is written on a design, it runs once for each copy: twelve chases of twelve gains (Designs: rules on a design run per copy).
The twelve: a loop that places copies
pathLanterns is a frameless holder, so its children are placed in the world's frame, and hiding it hides all twelve (Generators: a counted loop). The loop is Cone's each, twice: six pairs, and in each pair a side. land.walkway is found by name from the world's root, where land is (Parts: how a name is found). way.spotAt(way.fromEnd(...), across: side * 1.5 m) asks the walkway, a spine the land lays on its surface (Terrain), for the point a distance back along it from its end, 1.5 m out to its left (side -1) or its right (1), at right angles to its direction there (Sculpting: what a spine answers). The spot is a point (x, y, z) on the ground, so the lantern is placed at: spot and stands on the land; the walkway's spots read the land's height, so the land is built before the lanterns, though they are not inside it (Loading: order follows dependencies). A part declared in a loop is one of a numbered family, named with an index as a list's element is: lantern[2 * p + k] is read as lantern, and one of them as lantern[0], pair 0's on the left, nearest the steps, or lantern[11], pair 5's on the right, 15.8 m out. A copy states nothing but its place, so every other change to the design reaches all twelve. Its parts are pathLanterns.lantern[11].glass and so on (Parts: paths).
The wall lantern: a copy that changes
wallLantern: lanternHead(...) gives the head's own fields new values (size 0.7; a panel of one plate, drawn in the head's bronze, panelIn's default; the head hung 0.17 m out and below the bracket's top by the head's own height at 0.7 and 4 mm more, -(top * 0.7) - 4 mm, 0.327 m) and adds the bracket, a shape function of its own, drawn full size beside the head built at 0.7 (Construction: two kinds of scale). It has no area and no chase, so its gain stays 1. It also gives the common cdPerNit a value of its own, 1.2: the wall lanterns throw a stronger light from under the porch roof. A copy that sets a common field starts a family of its own: 1.2 is the one value of wallLantern and its two copies, and the path lanterns keep their 0.45 (Designs: a copy that sets a common field). The two copies hang on the cottage's porch, in the porch's frame. They are written in a file of their own whose lines declare them by a path, part cottage.porch.wallLantern1: wallLantern, at: (-0.7, 2.4, 0), under the porch, which the cottage's text declares once (Parts: a file that adds to a part).
Where it all runs
Only one line of the listing says which machine works something out (Distribution). The level, the glows and the light strengths are formulas of the clock and one start moment, so every machine works them out for itself. The gain is a chase, a value that remembers where it has got to, driven by near, and near is client: each visitor's machine works out its own visitor's nearness, its own chases and its own tints, and sends nothing. Had the lantern read occupied(post) instead, true while anyone is near, everyone would see a lantern brighten whoever stood by it (Lights: whose nearness).