fuzzyworld

tower / interior-flight / files / design.md

Branch interior-flight · default branch · all branches

design.md

49.2 KB · history · blame

Tower — Design

Tower is the setting of a novel. This app exists to serve that: first as an instrument for the author to see the place and keep it consistent, and second as a companion piece readers can explore. Where a choice trades spectacle against coherence, coherence wins — canon here is series-bible material, and the book is downstream of it.

Tower is a smart cylinder in orbit around Earth, spun for 1 g, with an inner surface the size of Wisconsin, lit by sunlight piped down its axis and scattered by a swarm of mirrors it flies itself. It is also a person.

The app has three linked views:

  1. Exterior — a 3D render of Tower from outside, with its collector, beam and orbit. You pick a point on the hull.
  2. Map — a 2D unrolled map of the inner surface. You pick a point here too; the two pickers stay in sync.
  3. Interior — a first-person "streetview" from the picked point, with live controls for time of day and spin phase.

1. Canon

1.1 Dimensions

All numbers derive from two free parameters — radius and length — chosen so the inner surface matches Wisconsin.

Quantity Value Notes
Radius 50 km floor to axis
Length 540 km sun cap to far cap
Wall depth 1 km floor to outer skin, D-044
Circumference 314.16 km the world's "width"
Inner surface area 169,646 km² Wisconsin total area, 169,635 km²
Habitable land area 169,646 km² all of it — the hull is sealed (§1.4)

Every square metre of the inner surface is land. There are no windows in the wall, so nothing is subtracted. An earlier version sized star slats to leave exactly Wisconsin's land area of 140,268 km²; D-017 removes them and that second coincidence with it.

1.2 Spin and gravity

Quantity Value
Angular velocity ω 0.014005 rad/s
Spin period 448.6 s = 7 min 29 s
Rotation rate 0.134 rpm
Rim speed 700.2 m/s
Floor gravity 1.000 g by construction

Consequences that the app should show or at least respect:

1.3 The sun system

Sunlight enters through the sun-facing end cap and runs the full 540 km axis.

1.3.0 Tower never sees the sun

The collector is 244 km across and flies 320 km ahead of the sun cap, which puts it 41.8° wide in Tower's sky against the sun's 0.53° — 79 times the sun's diameter. It sits squarely between Tower and the sun, so it occults it completely, and the umbra it casts is 120 km across where Tower's 51 km sits inside it. The eclipse is total, permanent, and self-inflicted.

So nobody aboard can see the sun, for the same reason nobody can see Earth (§1.4). What they can see, through the sun cap window, is the back of the collector: 46,938 km² of structure radiating its own waste heat at about 245 K — infrared, and therefore black. It is the only object in Tower's sky that is neither Tower nor a star, and it never moves, because the collector flies in formation rather than spinning. D-050.

Its edge is not black. The face is a mirror pointed away, but the collector is backlit, and the structure holding 46,938 km² flat stands proud of the mirror plane at the rim, where the sun strikes it side-on. With the scatter any real mirror throws at grazing incidence, the edge reads as a thin sun-coloured ring — so the collector is a hole in the stars with a lit rim rather than an absence, which is how anything backlit looks. It is not sunlight leaking past the edge: Tower is wholly inside the umbra, so the sun's disc is hidden from every point in the world. The ring is lit structure. D-054.

And Tower keeps its clock on it. Two lit lines from the collector's hub: one running the full radius, fixed normal to the plane of the solar system, and one stopping short of the rim at an angle θ from it, where θ runs 0 to 2π over a day. The collector is the only surface in the sky worth writing on — it does not spin, and it is always dead ahead through the sun cap window.

The time is the angle between the two lines, and it has to be. From inside, the whole collector face appears to wheel once every 7 min 29 s along with the stars, because the observer co-rotates and it does not. A single hand against a fixed dial would be unreadable, since the dial is not fixed; the angle between two marks is invariant under that rotation. It is a clock built for people who cannot stop the dial turning. D-055.

1.3.1 The diffuser swarm

The diffusers must be individually invisible, or the sky becomes a row of separate suns. Two thresholds govern this, and only the second one binds:

Diverting 54.3 TW needs 11.3 km² of mirror, so:

Mirrorlet size 1.2 cm, ~1.4 cm², 2 mg
Count 78 billion
Total mass 158 tonnes — the entire sun system
Mean spacing in beam 3.8 m — sparse enough to fly through
Optical depth over 540 km 1.41, so 24 % of light reaches the far cap

The swarm cannot be passive — it must fly, always. The axis is not weightless. At the beam's edge gravity is 0.312 m/s², enough that a foil sinks outward at 0.26 m/s and leaves the beam in 1.7 hours. A drifting swarm dissolves the same afternoon. Every foil is therefore under continuous individual control. This is not a flourish on a working system; it is the only configuration that works.

They have absurd power to do it with. Each foil intercepts 979 W of beam. Harvesting 0.1 % gives it ~1 W on a 2 mg body — 489,600 W/kg, some fifty times a jet engine's specific power.

Down-beam, riding radiation pressure 0.85 m/s, 7.4 days
Back up-beam under its own power at 1.5 m/s 15 µW, 4.2 days
Harvestable from ambient world-light 14,400 µW — a 1000× margin

So there is no recirculation machinery, at either cap. The foils fly home on scavenged daylight. Nothing needs to be built for them, and the 1000× power margin means Tower can afford to move them wastefully — in spirals, shoals and patterns that cost energy for no reason but preference.

Lighting is a render target, not a schedule. 78 billion independently aimed mirrors put any intensity on any patch of ground at any time. Dawn, dusk, moving cloud shadows and seasons are compositing problems, not optical ones.

Aiming resolution is human-sized. A 1.2 cm mirror is diffraction-limited to 4.6×10⁻⁵ rad, so its reflection lands as a 2.3 m spot on the floor 50 km below. Tower can put a glint on one person that someone five metres away cannot see. The privacy is set by the wavelength of light, not by any protocol.

Mirrorfall. A failed foil sinks out of the beam and falls. Terminal velocity at the floor is 0.48 m/s; the descent takes about two days and it lands like a snowflake. There is a permanent slow glitter coming down out of Tower's sky.

Illumination is a dial, not a constant

54.3 TW is Tower's capability, not its setting. Spread over the inner surface it is 320 W/m² mean, which — with roughly half the surface lit at a time and a sinusoidal day profile — puts local noon at ~1,000 W/m², Earth clear-sky daylight. But the diffusers are software-controlled, so brightness is genuinely adjustable in-world across the full range:

Setting Mean W/m² Feels like
Twilight 30 permanent overcast dusk
Temperate 200 Earth's global mean
Full 320 Earth clear-sky noon

This should be a control in the app, not a fixed number. It is the most characterful thing about a world whose sun is a machine.

Headroom

5,000× is 11 % of the étendue limit (46,223× at 1 AU). Tower could in principle push the beam 9.2× further and cook itself; the diffuser network is as much a safety system as a lighting system. 5,000× was chosen because it is demonstrated technology — the Odeillo solar furnace reaches ~10 MW/m² on Earth today. Nothing in Tower's sun system requires physics that does not exist. See decisions.md D-003.

1.3.2 Night, and the difference between banked and off

Night cannot be made by aiming the swarm away. The glow above belongs to the beam and the air, not to the diffusers, so a fully lit beam lights the world whatever the mirrorlets are doing: 779 W/m²/sr over a strip 3.65° wide running horizon to horizon is about 0.2 sr, which lands ~100 W/m² on the floor — half of temperate, and no kind of night. Tower's night is therefore made by banking the beam itself, to a thousandth of full: 0.32 W/m², a rod you can still find overhead and a world you can just make out under it (D-046).

Shutting the beam down entirely is a different state and a much worse one. No airlight, no lit ground, no rod — the only thing left in the world is the sky through the far cap. §1.9.4 gives the thermal mass about a week of coasting, so this is a state Tower can survive and not one it can sit in.

Setting Floor What it is
Dark 0 the beam shut down. Stars, and nothing else.
Night 0.32 W/m² the beam banked to a thousandth
Twilight 30 W/m²
Temperate 200 W/m²
Full 320 W/m² Earth clear-sky noon

1.3.3 The far cap mirror, and where the last quarter of the beam goes

The swarm has optical depth 1.41, so 24% of the beam survives all 540 km — and it survives collimated, in the beam's own 7.96 km² cross-section. That is the whole shape of the problem: not 13 TW spread over a 7,854 km² cap, but 1.7 MW/m² in a 3.2 km spot, about 1,200 suns. An absorber there sits at 2,330 K.

So the spot is a mirror (D-048), and only the spot: it is a thousandth of the cap's area, which is what leaves the other 99.9% free to be window (§1.4). A mirror is the cheap answer rather than the expensive one — at 99.9% it absorbs 1,665 W/m², about 1.2 Earth solar constants, so the thing that would have glowed white is merely warm.

It also recovers the energy. The residual goes back up the column, which makes the optical path 1,080 km instead of 540 and utilisation 1 - e^(-2τ) = 94% rather than 76%. What survives even the return trip leaves through the beam aperture toward the collector, which sends it back again; in the limit the whole 54.3 TW lands on the inner surface. This is why full brightness is 320 W/m² and not 243 — the figure in §1.3 assumes the entire beam is eventually used, and with the cavity closed at both ends it is.

Aiming light at a region to warm it is a separate lever and stays one (§1.9.4). The mirror is about not wasting the beam; the desert is about where the weather goes.

1.3.4 The day, and why dawn has a direction

Tower's day is 24 hours, chosen for the people living under it — nothing physical offers one, since the spin is 7.5 minutes and has nothing to do with light.

Dawn cannot be a dimmer, and it cannot be the swarm either. §1.3 gives the glow to the beam and the air, so the sky, the airlight and the rod overhead all brighten together the moment beam power comes up; there is no way to have one end of the axis light before the other. But the ground is lit by the diffusers, and they can put the light wherever they like. So Tower brings the day up as a front running deepward from the sun cap, 540 km in 40 minutes — 225 m/s, near Tower's own rim speed, and slow enough to stand and watch arrive.

The result is a morning nothing on Earth has: a fully lit sky over dark ground, with a line of daylight coming toward you along the world. §1.9.4 says Tower has no latitude. The cycle gives it longitude — 40 minutes of it, sun cap to far cap.

Dusk runs the same way, so the light withdraws in the direction it arrived and the sun-cap end always has the shorter day by a hair. Nothing forces that; the alternative was a dusk that retreats, and a consistent direction of time reads as designed rather than as an oscillation.

1.4 Sealed hull, and the cap windows

The cylinder wall is opaque and unbroken. No slats, no windows, no view out along any of the 540 km. From anywhere on the inner surface, the sky is land, haze and the beam — nothing else. See D-017.

The only views out are at the end caps, and they are peculiar:

Nobody aboard can ever see Earth. Tower holds a terminator orbit (D-004), which puts Earth roughly 90° off the axis — out the side of the cylinder, which is now solid hull. A habitat in Earth orbit whose inhabitants have never seen the planet they orbit.

The caps are therefore the only places in the world with a horizon that is not Tower. Whatever grows up around them, it will not be ordinary.

1.5 Atmosphere and the look of the sky

Air co-rotates with the shell. Because g falls linearly to zero at the axis, the atmosphere is much deeper than Earth's:

So the interior sky behaves like this, and the shader must reproduce it:

1.6 Orbit and attitude

1.7 Coordinates

The canonical surface coordinate is (θ, z):

The 2D map is the direct unroll: x = z, y = (θ − θ₀) · R. No projection distortion — a cylinder unrolls exactly. This is a genuine advantage over mapping a globe and the map view should lean on it.

The map shows the surface once, bounded, so its extent is readable. That means it needs an edge, and the edge is placed at θ₀ = the centre of the last slat. Land strip 0 is centred on θ = 0, so cutting there would slice a whole strip in half across the top and bottom margins; cutting at a slat centre leaves every land strip whole and splits only a band of stars, which carries no geography. Same reasoning as putting Earth's map edge at the antimeridian. A sightline whose short route crosses the edge is drawn as two segments, so the drawn path always matches the measured distance.


1.8 Sightlines: Tower has two horizons

Along the axis the floor is perfectly flat and never falls away, so nothing is ever hidden by curvature. Tower's horizon is haze. Circumferentially the floor curves up, so distant land rises into the sky rather than sinking below a line. The two directions behave completely differently, and this is one of the most alien facts about living there.

Rayleigh transmission from a floor-level observer:

Distance Along the axis Across the interior (overhead)
26 km 78 % 77 %
50 km 56 % 70 %
100 km 31 % 78 %
270 km (far cap from midpoint) 4 % — a ghost —

Two consequences:

1.9 Water

Tower's hydrology is stranger than its geometry, and most of it follows from one fact and one absence.

1.9.1 Coriolis never pushes surface water sideways

The floor's tangent plane is spanned by θ̂ and ẑ, and the spin axis is ẑ. For any flow along the surface:

The Coriolis term never has a component inside the surface. So Tower's rivers do not curve. No hemispheres, no Baer's law, no preferred bank erosion, no gyres, no cyclones. Every large-scale rotational habit of Earth's water and weather is absent, and a meander in Tower is pure flow dynamics with no thumb on the scale.

1.9.2 What it does instead: everything vertical leans

The force goes into the floor rather than across it, so it appears whenever water moves up or down. Deflection of a free fall goes as h^1.5:

Fall Lands (retrograde) Lean of the path Lean at impact
100 m 4.2 m 2.4° 3.6°
500 m 47 m 5.4° 8.1°
1,000 m 133 m 7.6° 11.3°
2,000 m 377 m 10.7° 15.8°

Two different angles, and the interior view needs both. The path leans by where the water lands against how far it fell — the tilt of a waterfall's plume seen whole. The impact lean is the direction the water is actually moving when it arrives, which is what a streak of it is drawn at, and it is half again the other in tangent. src/canon/motion.ts computes both.

Rain falls permanently slanted — a raindrop at terminal velocity sits at a fixed 1.47° against the spin, ~51 m of drift over a 2 km fall, never varying, never reversing. It is fixed because drag holds the fall speed constant, so unlike free fall the angle does not grow with the drop: rain leans the same 1.5° whatever the cloud. Set against a waterfall's 11°, the waterfall is the compass and the rain is not, which is the opposite of what §2.4 originally assumed (D-034). Rising things lean the opposite way: smoke drifts spinward, rain drifts anti-spinward. Every plume and every shower in Tower tilts, and they tilt against each other.

The same applies to anything that descends, not just water — see §1.11 on what it does to skiing.

Horizontal flow changes weight rather than direction (Eötvös): +0.57 % for a 2 m/s prograde river, negligible hydrologically. It only matters at speed — an express train at 100 m/s gains 29 %, and anything moving retrograde at the 700 m/s rim speed is stationary in space and therefore weightless.

1.9.3 A perfect cylinder has no slope anywhere

Potential depends only on radius, so the whole floor is a single equipotential surface. Water on it has no preferred direction: a perfect Tower has no rivers at all, forever.

Every river in Tower exists because the floor was shaped. There are no tectonics and no uplift, so erosion is strictly one-way — a 3 km range wears flat in ~30 Myr under a wet engineered climate, ~150 Myr under a dry one. Tower's rivers are steadily destroying its landscape and the highlands must be rebuilt to keep them running. This is D-004's theme again: Tower's rivers are plumbing it chose to install and has to keep re-installing.

Two corollaries:

1.9.4 There is no passive climate at all

Tower has no latitude — every point is equidistant from the light — and with the hull sealed it has no windows either. Nothing breaks the thermal uniformity. A uniform hull radiates at 274 K everywhere, so left alone the world settles into a flat calm: no gradient, no wind, no evaporation, no rain, no rivers.

So every weather system in Tower is deliberate. Tower makes climate the only way left to it — by aiming light. It warms where it wants convection and shades where it wants condensation; the hull's uniform loss is the sink. Every cloud, every rainfall, every jet stream is something Tower is doing, continuously, on purpose.

This is D-009 arriving at its conclusion. The mirrorlet swarm was already Tower's body language; now it is also its lungs and its weather. There is no autonomic layer underneath. If Tower's attention ever lapses, the rain stops.

Costs, for scale against a 54.3 TW budget:

Earth-like rainfall, 1,000 mm/yr 12.2 TW 22.4 % — Earth spends the same fraction
Recirculating all runoff (1,792 m³/s) against 500 m 8.8 GW 0.016 %

1.9.5 Rivers are a closed, pumped circulation

With no natural cycle and no natural slope, a Tower river is a loop: a headwater reservoir, a shaped descent through the landscape, a lake at the bottom, and a lift back to the top. Source and sink are the same system.

Two ways to close the loop, and they give completely different rivers:

Canon uses both — made weather for the world's general hydrology, pumps for watercourses Tower wants under precise control.

Two consequences of the sealed hull:

Lifting is also slightly cheaper than on Earth, since gravity falls off with height: 1 % cheaper at 1 km, 5 % at 5 km, 25 % at 25 km.

1.10 Slat orientation — RESOLVED: none

Axial strips versus rings was weighed at length (D-016) and answered by removing slats entirely (D-017). The comparison is kept in D-016 because it established what the choice cost, and because the reasoning — that slat layout sets the shape of Tower's countries, its climate map and its astronomy all at once — is what made "none" a real option rather than an absence.

1.11 The world as built

Authored geography lives in content/geography.json — the source of truth — and npm run terrain renders it. Names are provisional. Tower is laid out in belts along the axis, which is the natural grain of an engineered climate (§1.9.4):

z
0–42 km The Sunward Sea ring ocean at the foot of the sun cap
55–140 km the range Westwall, The Sisters, Snowcrown (4,300 m), Eastwall — the named high points of The Girdle, which rings the world at z 90 km (D-051)
148–218 km The Dry Reach desert ringing the world, 22,000 km², 13% of the surface
176/190/203 km three ridges ringing, concentric — and The Narrows is the only breach in all three
214–430 km Greatwood forest belt
248–402 km The Deep 154 × 32 km sea, long down the axis and narrow around
270 km The Capital / The Spindle axial midpoint, on The Deep's antispinward shore
496–540 km The Deepward Sea ring ocean at the foot of the far cap

Why the desert rings

On a cylinder you cannot go around a band. Every desert on Earth can be circumnavigated; a ringed one cannot. It is an absolute barrier across the world's waist, and with the three ridges ringing too it becomes three concentric walls.

The drainage, and why it keeps the chokepoint

Four rivers come off the range — Westwall Water, Sisters Water, Eastwall Water and The Long Water. On Earth most drainages do not cut through a rising ridge; they are defeated and diverted, and only an antecedent river with enough power keeps its course. So three of the four are turned by First Ridge, run along its front gathering each other, and leave with the fourth through the single gap.

The Deep is oriented for the view

Long down the axis and narrow around it, so you cross it the short way — around θ, where the floor curves up. From the Capital the far shore is 32 km away and stands 2.6 km above eye level. Crossing it lengthwise instead would be dead flat. The orientation is the whole point.

It is also the world's flywheel: 19× the diurnal heat storage of bare ground, and 5.9 days at full power to move its temperature one kelvin. Tower still supplies every joule (§1.9.4), but the world now coasts for about a week rather than stopping the moment attention lapses.

The cap seas are not designed

Gravity on an end cap points radially outward — tangent to the cap. Nothing rests there; water runs down to the rim and pools. Both ring oceans exist whether anyone planned them or not, each with a 314 km shoreline and a 50 km cliff standing behind it. The only windows in the world are at their feet (§1.4).

Skiing, because it is a different sport here

Level motion feels no Coriolis (§1.9.1) but a descending skier has radial velocity, and that does deflect:

So a retrograde run gets lighter the faster you go, which is self-reinforcing, while a prograde run grips harder as it accelerates. Every slope in Tower has a handedness. No Earth mountain does. Settlements sit at the tarns — Sisters Station, Hollow Station — around 2,100 m, with the runs above them.

Open questions

2. Application architecture

2.1 Stack

2.2 Module layout

src/
  canon/
    constants.ts    single source of truth for every number in §1
    geometry.ts     (θ,z) <-> 3D, slat layout, map <-> surface
    atmosphere.ts   the rotational density profile and its extinction (§1.5)
    motion.ts       how things fall in the rotating frame (§1.9.2) — the only
                    evidence of the spin anywhere but the far cap window
  views/
    palette.ts      one colour per place kind, shared by map, list and editor
    raster.ts       what npm run terrain wrote: grid, and what white means
  world/
    schema.ts       world.json types + validation
    store.ts        places CRUD, localStorage drafts, JSON import/export
    instruments.ts  sightline, viewshed, lighting probe, travel (§3.3)
  state/
    store.ts        selected point, time-of-day, spin phase, view mode, writer flag
  views/
    exterior.ts     Three.js: hull, caps, collector, beam, spin, point picker
    map.ts          Canvas 2D: unrolled surface, slats, terminator, point picker
    interior.ts     Three.js: shell geometry, the haze shader of §1.5, beam, rain
  ui/
    app.ts          the whole panel: tools, editor, readouts, view switching
    scales.ts       slider mappings — kept out of views/ so the panel can label
                    the eye-height slider without pulling in Three.js
  main.ts

tools/                node-only, never bundled; plain .mjs with no build step
  terrain.mjs         renders content/geography.json into static/ (§1.11)
  png.mjs             minimal PNG encoder — zlib is its only dependency
  noise.mjs           fbm and ridged noise for the terrain relief
  screenshots.mjs     drives the running application in a headless browser and
                      photographs it into docs/screenshots/ (D-042)

canon/constants.ts is the spine. Every derived figure — period, rim speed, land area, slat width — is computed from radius, length, slat count and target land area, never hard-coded. Changing the radius changes the whole app coherently.

2.3 State

One small observable store. Views subscribe; nothing owns anything else.

type TowerState = {
  point: { theta: number; z: number } | null  // the picked location
  tod: number        // 0..1, position in the diffuser day cycle
  brightness: number // W/m^2 mean, 30..320 -- the diffuser output setting
  spinPhase: number  // 0..2pi, rotation for star motion
  spinning: boolean
  view: 'exterior' | 'map' | 'interior'
  writer: boolean    // ?writer=1 -- a UI mode, not a security boundary
  probe: { from: SurfacePoint; to: SurfacePoint } | null
}

The exterior and map pickers both write point; the interior view reads it. That is the entire interaction loop.

2.4 The exterior view

Scene units are kilometres, so the code reads in canon numbers. Tower's axis lies along world Z with the sun cap at z = 0, which puts a canon surface point at (R cos θ, R sin θ, z) in the hull's own frame. The hull spins about Z and carries that frame with it, so picking resolves the ray hit back through worldToLocal — otherwise every point picked off a turning hull would be wrong by the spin phase.

Two deliberate departures from physics, both reading aids of the same kind as the map's hillshade:

Everything in the scene is captioned — collector, beam, both caps — with screen-space labels. A pale disc and a cone of light are not self-explanatory, and the collector is the least intuitive object in Tower: it is larger than the world it feeds.

The default camera frames the whole system rather than Tower alone: the collector is 244 km across and flies 320 km ahead, and it is the larger object.

The hull has two readings, and the view switches between them (D-047). True is the outer skin: bare structure, the checkered sun cap, and the glazed far cap. X-ray wraps the terrain raster onto the outside instead — from outside Tower is structure, so what that texture shows is what is inside, which makes it a diagram and not a view. Both are worth having and they are not the same claim, so the control is a two-way switch rather than a checkbox.

The wall is drawn as two meshes rather than one double-sided one, because its two faces show different things: the outer skin changes with the mode, and the inner surface is always the land. Since the far cap became a window (D-045) that inner surface is genuinely visible from outside — look in through the glass in true mode and the world is really there, lit and 540 km deep. It is the only line of sight into Tower that is not a projection. Three's cylinder runs u around and v along, while the raster is the other way round, so the UVs are rewritten from the original attribute rather than derived from vertex positions — the seam vertices are duplicated, and deriving an angle from them smears one column of triangles across the whole image.

The camera position persists across reloads, alongside the active view, so returning to the page returns to the vantage you left. Both end caps are places in their own right, so the view can frame them: a cap's marker sits on the axis, because a cap is a disc across the end and a point on its rim would ride round the edge as Tower turns.

Markers are scaled per frame to hold a roughly constant size on screen. A 4 km dot is legible from 200 km and sub-pixel from the 1,200 km of the default view, which is to say the places would simply not be there.

2.4 The interior view — built

Scope held: real geometry, simple ground.

Real: the shell is the actual cylinder, curving up on both sides and closing overhead, displaced by terrain-height.png and painted with terrain-color.png. Stars only through the far cap — the wall is sealed (§1.4), so for 539 of the 540 km the sky is land and light. The far cap is glazed (D-045) and the sky beyond it is sampled by view direction in an azimuthal-equidistant projection about the spin axis, which makes the pinwheel fall out of the projection rather than being animated into it: azimuth plus spin phase, one turn every 7 min 29 s, and the point on the axis genuinely motionless.

Simple: the ground is the raster plus a little procedural grain in the near field, not modelled scenery. No buildings, no vegetation meshes. Cells are 0.7 km and texels 264 m, so relief a valley away is real and the ground underfoot is not. Detailed procedural scenery stays deferred.

Haze is the shader, and it is integrated rather than faked. Every fragment samples the rotational density profile 24 times along the ray to the camera and extinguishes per channel — red survives twice as far as green, blue half as far, which is what makes distance blue rather than grey. From the floor it reproduces §1.8 from the inside: 78% straight up against 31% for the same 100 km along the ground, printed in the readout so the claim can be checked rather than believed. The airlight the haze adds is neutral; tinting it blue double-counts the wavelength dependence and turns even the desert mauve (D-034).

Nothing inside the scene rotates, because the observer, the ground and the air all co-rotate. What falls carries the spin, and §1.9.2 is lopsided about how: rain leans a fixed 1.5° whatever the cloud, because drag pins its speed, while only free fall keeps accelerating and so keeps leaning. The waterfall is the compass; the rain is barely a hint. Rain is no longer drawn (D-049) — 1.5° is not a picture, and the pinwheel below does the job it was standing in for. The physics stays in canon/motion.ts and stays tested; it was only ever the rendering that could not carry it.

The one thing that does turn is outside. The sky through the caps does not co-rotate, so it wheels once every 7 min 29 s about the motionless star on the axis (D-045). It is by a wide margin the plainest evidence of the spin in the view, and it is the only evidence left now that the rain is gone. Both caps are windows (D-050), so it can be had looking either way along the axis — deepward into empty space, or sunward past the black disc of the collector.

The observer stands on the terrain, which means the height raster is read back onto the CPU and sampled against the mesh's own cell corners — the GPU cannot be asked where the ground is (D-035).

Instruments in the view: eye height from 1.7 m to 25 km with the local gravity beside it, the five canon illumination settings of §1.3, the field of view as a pair of binoculars, and captions on every place still visible through the haze. Selecting a place walks the observer to it (D-038) — the haze horizon closes at 100–150 km, so turning to face something usually just points at haze.

The caps are no longer the same object. The sun cap is checkered (D-041) — polar, six rings, cells about 8 km. The far cap is glazed (D-045), and the checker survives on it as the window's mullions: the same tessellation at the same pitch, so it is still the only object in the world with a known size and still doubles as a scale for judging distance, now read against sky rather than plate. Both patterns are shared with the exterior view.

The far cap's glazing is set a kilometre into its own frame, so from inside there is a 1 km reveal around it. That is the only place the wall depth of D-044 can be seen from within the world, which is why it is the only place it is drawn.

Not modelled: water has no surface. Lakes and seas are painted in the raster and cut into the shell as basins, so standing in one puts you on its floor.


3. Writer mode and the world file

The app is an instrument for writing the novel as much as a thing to look at. It must answer questions like can the far face be seen from the midpoint?, where does a central embassy go?, can a lake overhang? — and let their answers be placed, named and kept.

3.1 Two modes over one data file

Reader (default) Writer (?writer=1)
World content committed world.json, read-only editable, drafts in localStorage
Instruments (§3.3) sightline probe only all
Output permalinks to a point or place Export JSON for the author to commit
Panel read-only detail card full editor, canon controls, import/export

There is no backend — GitLab Pages is static. The loop is: the author edits in the browser, exports world.json, commits it, and the published site serves it. Simple, versioned in git alongside the prose, and diffable.

Writer mode is a UI mode, not a security boundary. Anyone may set ?writer=1; they can only edit their own local copy, which persists nowhere and reaches nobody. This is fine, and arguably good — a reader who finds it gets a sandbox. It must not be mistaken for access control.

3.2 The world file

{
  "version": 1,
  "places": [{
    "id": "hallow-crossing",          // permalink target; see below
    "name": "Hallow Crossing",
    "kind": "city|embassy|lake|region|landmark|note",
    "geometry": { "type": "point",   "theta": 1.9635, "z": 270000 },
    //        or { "type": "polygon", "points": [[theta,z], ...] }   for lakes, regions
    "blurb": "public description, shown to readers",
    "notes": "the author's working notes — NEVER shipped",
    "public": true                    // false = not ready to exist publicly
  }]
}

Two text fields, deliberately separate. blurb is written for readers and ships; notes is the author's working thinking and never leaves the machine except in a backup. One field with a flag would have made every note a publication accident waiting to happen.

Ids follow the name until pinned. An id is a permalink target and must be stable once published, but during world-building names churn constantly and a file full of new-city-7 is unreadable. So the id tracks the name while it still matches it, and editing the id field freezes it for good. The editor shows the id for exactly this reason.

Coordinates are canon (θ radians, z metres, §1.7) — never map pixels, so the file survives any change to how the map is drawn.

The public flag is a privacy trap worth naming. Working notes ("embassy here? check sightline to the cap") must not ship to readers. But a world.json committed to a public repository is public regardless of any flag in it. So export writes two files: world.json (public entries only, committed) and world.private.json (everything, gitignored by default). Whether private notes should nonetheless be version-controlled — in a private repo, or a second one — is the author's call and is deliberately unresolved.

3.3 Instruments

The measuring tools are the real substance of writer mode. Each answers a question the novel actually raised:

3.4 What readers get

The public link is the finished map: embassies, towns, lakes, named regions — the permanent things, behaving like any map application. Plus the exterior view, the interior view from any point, and permalinks so a reader can be handed a place and a moment. Reading the world, not editing it.

4. Phases

  1. Design — this document and decisions.md. ← current
  2. Scaffold — Vite/TS/Three, CI to Pages, canon/ implemented and unit-tested.
  3. Exterior — ✅ hull, caps, collector, beam, spin, and hull point picking.
  4. Map — unrolled surface, slat rendering, picking, sync with exterior.
  5. Interior — ✅ shell geometry, the haze shader, the beam, rain, eye height, and the five illumination settings. Stars, but only through the far cap window.
  6. Writer mode — ✅ built ahead of 3–5, at the author's request, because the world needs developing before there is anything to render. Map view, place editing for all thirteen kinds, points/polylines/polygons, localStorage autosave, backup and static exports, import, and the sightline probe.
  7. Content pipeline and reader mode — ✅ content/geography.json + npm run terrain (D-019); the rendered terrain drawn under the map; reader and writer modes (D-011); permalinks (D-010).
  8. Polish — mobile ✅ (the sidebar is a drawer below 720 px, D-043) and a screenshot tour that photographs all ten views through the UI, D-042. Remaining: transitions, performance.

All five view phases are built. Phase 2's canon/ landed with phase 6, since the map could not be drawn without it.

Shareable permalinks are implemented (phase 7) — the app has readers, and "stand here and look at this" is the whole reason it exists as a companion piece. Named locations from the novel should be markable on the map for the same reason.

Later, explicitly out of scope for now: procedural scenery, settlements, weather systems.

Source
1# Tower — Design
2
3**Tower is the setting of a novel.** This app exists to serve that: first as an
4instrument for the author to see the place and keep it consistent, and second as a
5companion piece readers can explore. Where a choice trades spectacle against
6coherence, coherence wins — canon here is series-bible material, and the book is
7downstream of it.
8
9Tower is a smart cylinder in orbit around Earth, spun for 1 g, with an inner
10surface the size of Wisconsin, lit by sunlight piped down its axis and scattered by
11a swarm of mirrors it flies itself. It is also a person.
12
13The app has three linked views:
14
151. **Exterior** — a 3D render of Tower from outside, with its collector, beam and
16 orbit. You pick a point on the hull.
172. **Map** — a 2D unrolled map of the inner surface. You pick a point here too; the
18 two pickers stay in sync.
193. **Interior** — a first-person "streetview" from the picked point, with live
20 controls for time of day and spin phase.
21
22---
23
24## 1. Canon
25
26### 1.1 Dimensions
27
28All numbers derive from two free parameters — radius and length — chosen so the
29inner surface matches Wisconsin.
30
31| Quantity | Value | Notes |
32|---|---|---|
33| Radius | **50 km** | floor to axis |
34| Length | **540 km** | sun cap to far cap |
35| Wall depth | **1 km** | floor to outer skin, D-044 |
36| Circumference | **314.16 km** | the world's "width" |
37| Inner surface area | **169,646 km²** | Wisconsin total area, 169,635 km² |
38| Habitable land area | **169,646 km²** | all of it — the hull is sealed (§1.4) |
39
40Every square metre of the inner surface is land. There are no windows in the wall,
41so nothing is subtracted. *An earlier version sized star slats to leave exactly
42Wisconsin's land area of 140,268 km²; D-017 removes them and that second
43coincidence with it.*
44
45### 1.2 Spin and gravity
46
47| Quantity | Value |
48|---|---|
49| Angular velocity ω | **0.014005 rad/s** |
50| Spin period | **448.6 s** = 7 min 29 s |
51| Rotation rate | **0.134 rpm** |
52| Rim speed | **700.2 m/s** |
53| Floor gravity | **1.000 g** by construction |
54
55Consequences that the app should show or at least respect:
56
57- **Gravity falls off linearly with height.** g(h) = ω²(R−h). A 1 km peak sits at
58 0.98 g; the axis is weightless. Mirrors at the axis float.
59- **Coriolis is mild but real.** 2ω = 0.0280 s⁻¹. Walking is unaffected (0.4 % g).
60 A ball thrown at 30 m/s deflects at 8.6 % g — enough that Tower's sports differ
61 from Earth's, and enough that thrown objects visibly curve.
62- **Nothing in the sky moves, except through the far cap.** The wall is sealed
63 (§1.4), so along 539 of the 540 km there is nothing to wheel past — the far side
64 of the world overhead co-rotates with you and hangs perfectly still. The one
65 exception is the far cap window, where the sky is *outside* and does not
66 co-rotate: it turns once every 7 min 29 s about a single motionless star on the
67 axis. The spin is invisible upward and obvious deepward, and only at night.
68- **But everything that falls leans.** Rain hangs at a permanent 1.47° slant, smoke
69 drifts the other way, and a 1 km waterfall lands 133 m off its own cliff (§1.9.2).
70 This inversion is the alien fact the interior view must sell: **the sky is still
71 and the water is not.**
72
73### 1.3 The sun system
74
75Sunlight enters through the sun-facing end cap and runs the full 540 km axis.
76
77- **Collector.** A mirror array flies ahead of Tower, gathering sunlight and
78 concentrating it into the beam. **46,900 km² of aperture — a disc ~244 km
79 across**, two and a half times Tower's own diameter. It is the dominant visual
80 element of the exterior view.
81- **Beam.** **10 km in circumference** — 1,592 m radius, 7.96 km² cross-section —
82 carrying **54.3 TW** at a concentration of **5,000×**, or 6.8 MW/m². It runs the
83 axis from sun cap to far cap.
84- **Diffusers.** Not lamps — a **swarm**. See §1.3.1.
85- **The beam is visible, and it glows by itself.** There is real air at the axis
86 (§1.5), and a 6.8 MW/m² beam Rayleigh-scattering through 3.18 km of it radiates
87 **779 W/m²/sr** — **26× brighter than clear blue sky, 25,700× dimmer than the
88 sun's disc.** It is a brilliantly sunlit cloud extruded into a rod, safe to look
89 at directly. From the floor 50 km below it is **3.65° wide, about seven
90 sun-widths**, running the whole length of the sky. This glow is a property of the
91 beam and the air, not of the diffusers — it would be there if the beam were empty.
92
93#### 1.3.0 Tower never sees the sun
94
95The collector is **244 km across and flies 320 km ahead of the sun cap**, which puts
96it **41.8° wide** in Tower's sky against the sun's 0.53° — **79 times the sun's
97diameter**. It sits squarely between Tower and the sun, so it occults it completely,
98and the umbra it casts is 120 km across where Tower's 51 km sits inside it. The
99eclipse is total, permanent, and self-inflicted.
100
101So **nobody aboard can see the sun**, for the same reason nobody can see Earth
102(§1.4). What they can see, through the sun cap window, is the *back* of the
103collector: 46,938 km² of structure radiating its own waste heat at about 245 K —
104infrared, and therefore black. It is the only object in Tower's sky that is neither
105Tower nor a star, and it never moves, because the collector flies in formation
106rather than spinning. D-050.
107
108**Its edge is not black.** The face is a mirror pointed away, but the collector is
109*backlit*, and the structure holding 46,938 km² flat stands proud of the mirror
110plane at the rim, where the sun strikes it side-on. With the scatter any real mirror
111throws at grazing incidence, the edge reads as a thin sun-coloured ring — so the
112collector is a hole in the stars with a lit rim rather than an absence, which is how
113anything backlit looks. **It is not sunlight leaking past the edge**: Tower is wholly
114inside the umbra, so the sun's disc is hidden from every point in the world. The ring
115is lit structure. D-054.
116
117**And Tower keeps its clock on it.** Two lit lines from the collector's hub: one
118running the full radius, fixed normal to the plane of the solar system, and one
119stopping short of the rim at an angle θ from it, where θ runs 0 to 2π over a day.
120The collector is the only surface in the sky worth writing on — it does not spin,
121and it is always dead ahead through the sun cap window.
122
123**The time is the angle between the two lines, and it has to be.** From inside, the
124whole collector face appears to wheel once every 7 min 29 s along with the stars,
125because the observer co-rotates and it does not. A single hand against a fixed dial
126would be unreadable, since the dial is not fixed; the angle between two marks is
127invariant under that rotation. It is a clock built for people who cannot stop the
128dial turning. D-055.
129
130#### 1.3.1 The diffuser swarm
131
132The diffusers must be individually invisible, or the sky becomes a row of separate
133suns. Two thresholds govern this, and only the second one binds:
134
135- **Resolvability.** At 50 km, one arcminute is 14.5 m. Anything larger is a
136 resolved disc with a visible edge.
137- **Visibility.** Being unresolved is not enough — stars are unresolved and we see
138 them. A mirror *preserves radiance*, so a mirrorlet aimed at an observer shows
139 the sun's own surface brightness over a tiny angle. A 1 m mirrorlet reads at
140 magnitude −13.6, brighter than the full moon. Blending into daylight requires
141 **~1.2 cm**, at magnitude −4.0, just under Venus.
142
143Diverting 54.3 TW needs 11.3 km² of mirror, so:
144
145| | |
146|---|---|
147| Mirrorlet size | **1.2 cm**, ~1.4 cm², 2 mg |
148| Count | **78 billion** |
149| Total mass | **158 tonnes** — the entire sun system |
150| Mean spacing in beam | **3.8 m** — sparse enough to fly through |
151| Optical depth over 540 km | 1.41, so **24 % of light reaches the far cap** |
152
153**The swarm cannot be passive — it must fly, always.** The axis is not weightless.
154At the beam's edge gravity is **0.312 m/s²**, enough that a foil sinks outward at
1550.26 m/s and **leaves the beam in 1.7 hours**. A drifting swarm dissolves the same
156afternoon. Every foil is therefore under continuous individual control. This is not
157a flourish on a working system; it is the only configuration that works.
158
159**They have absurd power to do it with.** Each foil intercepts 979 W of beam.
160Harvesting 0.1 % gives it ~1 W on a 2 mg body — **489,600 W/kg**, some fifty times
161a jet engine's specific power.
162
163| | |
164|---|---|
165| Down-beam, riding radiation pressure | 0.85 m/s, 7.4 days |
166| Back up-beam under its own power at 1.5 m/s | 15 µW, 4.2 days |
167| Harvestable from ambient world-light | **14,400 µW** — a 1000× margin |
168
169**So there is no recirculation machinery, at either cap.** The foils fly home on
170scavenged daylight. Nothing needs to be built for them, and the 1000× power margin
171means Tower can afford to move them *wastefully* — in spirals, shoals and patterns
172that cost energy for no reason but preference.
173
174**Lighting is a render target, not a schedule.** 78 billion independently aimed
175mirrors put any intensity on any patch of ground at any time. Dawn, dusk, moving
176cloud shadows and seasons are compositing problems, not optical ones.
177
178**Aiming resolution is human-sized.** A 1.2 cm mirror is diffraction-limited to
1794.6×10⁻⁵ rad, so its reflection lands as a **2.3 m spot** on the floor 50 km below.
180Tower can put a glint on one person that someone five metres away cannot see. The
181privacy is set by the wavelength of light, not by any protocol.
182
183**Mirrorfall.** A failed foil sinks out of the beam and falls. Terminal velocity at
184the floor is 0.48 m/s; the descent takes about two days and it lands like a
185snowflake. There is a permanent slow glitter coming down out of Tower's sky.
186
187#### Illumination is a dial, not a constant
188
18954.3 TW is Tower's *capability*, not its setting. Spread over the inner surface it
190is 320 W/m² mean, which — with roughly half the surface lit at a time and a
191sinusoidal day profile — puts **local noon at ~1,000 W/m², Earth clear-sky
192daylight**. But the diffusers are software-controlled, so brightness is genuinely
193adjustable in-world across the full range:
194
195| Setting | Mean W/m² | Feels like |
196|---|---|---|
197| Twilight | 30 | permanent overcast dusk |
198| Temperate | 200 | Earth's global mean |
199| **Full** | **320** | **Earth clear-sky noon** |
200
201This should be a control in the app, not a fixed number. It is the most
202characterful thing about a world whose sun is a machine.
203
204#### Headroom
205
2065,000× is **11 % of the étendue limit** (46,223× at 1 AU). Tower could in principle
207push the beam 9.2× further and cook itself; the diffuser network is as much a safety
208system as a lighting system. 5,000× was chosen because it is *demonstrated*
209technology — the Odeillo solar furnace reaches ~10 MW/m² on Earth today. Nothing in
210Tower's sun system requires physics that does not exist. See `decisions.md` D-003.
211
212#### 1.3.2 Night, and the difference between banked and off
213
214**Night cannot be made by aiming the swarm away.** The glow above belongs to the
215beam and the air, not to the diffusers, so a fully lit beam lights the world
216whatever the mirrorlets are doing: 779 W/m²/sr over a strip 3.65° wide running
217horizon to horizon is about 0.2 sr, which lands **~100 W/m² on the floor** — half
218of temperate, and no kind of night. Tower's night is therefore made by **banking
219the beam itself**, to a thousandth of full: **0.32 W/m²**, a rod you can still find
220overhead and a world you can just make out under it (D-046).
221
222**Shutting the beam down entirely is a different state and a much worse one.** No
223airlight, no lit ground, no rod — the only thing left in the world is the sky
224through the far cap. §1.9.4 gives the thermal mass about a week of coasting, so
225this is a state Tower can survive and not one it can sit in.
226
227| Setting | Floor | What it is |
228|---|---|---|
229| Dark | **0** | the beam shut down. Stars, and nothing else. |
230| Night | **0.32 W/m²** | the beam banked to a thousandth |
231| Twilight | 30 W/m² | |
232| Temperate | 200 W/m² | |
233| Full | 320 W/m² | Earth clear-sky noon |
234
235#### 1.3.3 The far cap mirror, and where the last quarter of the beam goes
236
237The swarm has optical depth 1.41, so **24% of the beam survives all 540 km** — and
238it survives *collimated*, in the beam's own 7.96 km² cross-section. That is the
239whole shape of the problem: not 13 TW spread over a 7,854 km² cap, but **1.7 MW/m²
240in a 3.2 km spot**, about 1,200 suns. An absorber there sits at **2,330 K**.
241
242**So the spot is a mirror** (D-048), and only the spot: it is a thousandth of the
243cap's area, which is what leaves the other 99.9% free to be window (§1.4). A mirror
244is the cheap answer rather than the expensive one — at 99.9% it absorbs **1,665
245W/m²**, about 1.2 Earth solar constants, so the thing that would have glowed white
246is merely warm.
247
248**It also recovers the energy.** The residual goes back up the column, which makes
249the optical path 1,080 km instead of 540 and utilisation **1 - e^(-2τ) = 94%**
250rather than 76%. What survives even the return trip leaves through the beam
251aperture toward the collector, which sends it back again; in the limit the whole
25254.3 TW lands on the inner surface. **This is why full brightness is 320 W/m² and
253not 243** — the figure in §1.3 assumes the entire beam is eventually used, and with
254the cavity closed at both ends it is.
255
256Aiming light at a region to warm it is a separate lever and stays one (§1.9.4). The
257mirror is about not wasting the beam; the desert is about where the weather goes.
258
259#### 1.3.4 The day, and why dawn has a direction
260
261Tower's day is **24 hours**, chosen for the people living under it — nothing
262physical offers one, since the spin is 7.5 minutes and has nothing to do with light.
263
264**Dawn cannot be a dimmer, and it cannot be the swarm either.** §1.3 gives the glow
265to the beam and the air, so the sky, the airlight and the rod overhead all brighten
266together the moment beam power comes up; there is no way to have one end of the axis
267light before the other. But the *ground* is lit by the diffusers, and they can put
268the light wherever they like. So Tower brings the day up as a **front running
269deepward from the sun cap**, 540 km in 40 minutes — **225 m/s**, near Tower's own rim
270speed, and slow enough to stand and watch arrive.
271
272The result is a morning nothing on Earth has: **a fully lit sky over dark ground**,
273with a line of daylight coming toward you along the world. §1.9.4 says Tower has no
274latitude. The cycle gives it **longitude** — 40 minutes of it, sun cap to far cap.
275
276Dusk runs the same way, so the light withdraws in the direction it arrived and the
277sun-cap end always has the shorter day by a hair. Nothing forces that; the
278alternative was a dusk that retreats, and a consistent direction of time reads as
279designed rather than as an oscillation.
280
281### 1.4 Sealed hull, and the cap windows
282
283**The cylinder wall is opaque and unbroken.** No slats, no windows, no view out
284along any of the 540 km. From anywhere on the inner surface, the sky is land, haze
285and the beam — nothing else. See D-017.
286
287The only views out are at the **end caps**, and they are peculiar:
288
289- **A cap is a wall, not a floor.** Gravity there points radially outward, which is
290 *tangent* to the cap's surface, so nothing rests on it — you would slide to the
291 rim. Each cap is a **50 km vertical cliff** standing at the end of the world, and
292 its windows sit at its base, at eye level for anyone standing on the floor.
293- **The sky through them does not sweep — it turns.** A cap window looks along the
294 spin axis, which is the celestial pole. Stars rotate about a fixed centre, one
295 full turn every 7.5 minutes, with one motionless star at the middle. **A pinwheel
296 sky.** It is the only moving sky anyone in Tower ever sees — and because the axis
297 is horizontal from the floor, it wheels about a point on the **horizon** rather
298 than overhead.
299- The **far cap is glazed whole** — a 100 km window looking into deep anti-sun
300 space, not a wall with windows at its foot (D-045). Its structure survives as the
301 window's **mullions**, on the same polar tessellation the checker used and at the
302 same cell pitch, so the one object in the world with a known scale still is one:
303 the rule now reads against the sky instead of against a plate. The **sun cap**
304 faces the collector rather than the sun, and is **glazed too** (D-050): §1.3.0
305 retires the "heavy glare management" this section used to demand of it, because no
306 direct sunlight has ever reached it. Through it, a 244 km black disc, stars round
307 the edge of it, and the beam blazing out of the aperture at its centre.
308- **By day the window is simply blue.** §1.5 puts the far cap 100–200 km into the
309 haze, so from anywhere but the deepward end the airlight in front of it swamps
310 whatever is behind, and the cap reads as a disc of sky. The stars are there at
311 noon and unseeable, which is a fact about eyes and not about the glass.
312- **The beam does not go through it.** §1.3.3 puts the surviving quarter of the
313 beam on a 3.2 km bullseye at the centre of the cap, and that bullseye is a mirror
314 rather than glass: it returns the residual up the column for a second pass. The
315 window is everything else, which is 99.9% of the disc.
316- **The mirror is not the pinwheel's centre, and it is worth being clear why.** The
317 sky turns about the direction *parallel* to the spin axis, and from anywhere on
318 the floor that direction is horizontal — so **the pinwheel's centre is at eye
319 level, dead ahead**, down where the window meets the ground, not overhead and not
320 at the middle of the cap. The mirror is a physical object *on* the axis, which
321 from 270 km sits about 10° above that. They coincide only for an observer
322 standing on the axis itself, and nobody can. By day the mirror blazes — it is
323 returning 1.7 MW/m² — and is the brightest thing in Tower's sky; at night it
324 banks with the beam and goes dark.
325
326**Nobody aboard can ever see Earth.** Tower holds a terminator orbit (D-004), which
327puts Earth roughly 90° off the axis — out the *side* of the cylinder, which is now
328solid hull. A habitat in Earth orbit whose inhabitants have never seen the planet
329they orbit.
330
331The caps are therefore the only places in the world with a horizon that is not
332Tower. Whatever grows up around them, it will not be ordinary.
333
334### 1.5 Atmosphere and the look of the sky
335
336Air co-rotates with the shell. Because g falls linearly to zero at the axis, the
337atmosphere is much deeper than Earth's:
338
339- Pressure at the axis, 50 km up: **5.2 kPa** — thin, but genuinely air.
340- A vertical column floor-to-axis is ~10,600 kg/m², about **one Earth atmosphere**.
341
342So the interior sky behaves like this, and the shader must reproduce it:
343
344- **Straight up** you look through ~1 atmosphere and see the far side of the world
345 100 km away — visible, but washed to pale blue like a very distant mountain range.
346- **Along the axis** you look through many atmospheres. The far end cap is not
347 visible as a wall; it dissolves into blue haze around 100–200 km out. The world
348 reads as endless in the axial direction and closed in the circumferential one.
349- **The ground curves up on both sides** into that same blue, meeting overhead.
350- **The beam** is a self-luminous scattering shaft 3.65° wide at 779 W/m²/sr —
351 render it as a bright sunlit cloud, not as a light source with a halo. With the
352 hull sealed, it is the only thing in the sky that is not land.
353
354### 1.6 Orbit and attitude
355
356- Tower holds a high circular orbit with its **orbital plane kept normal to the
357 Earth–Sun line** — a terminator orbit. This is why one cap can face the sun
358 permanently and Tower is never eclipsed.
359- The plane precesses 360° per year to track the sun. Tower's angular momentum is
360 enormous, so this 1°/day reorientation is actively driven, continuously, forever.
361 Canon treats this as Tower's defining maintenance burden.
362- Consequence for the interior view: the star field slowly drifts across the year
363 while spinning fast every 7.5 minutes. Two nested motions.
364
365### 1.7 Coordinates
366
367The canonical surface coordinate is **(θ, z)**:
368
369- `θ` — angle around the cylinder, 0 to 2π. θ = 0 is the centre of land strip 0.
370- `z` — distance from the sun cap, 0 to 540 km.
371
372The 2D map is the direct unroll: `x = z`, `y = (θ − θ₀) · R`. No projection
373distortion — a cylinder unrolls exactly. This is a genuine advantage over mapping a
374globe and the map view should lean on it.
375
376**The map shows the surface once, bounded**, so its extent is readable. That means
377it needs an edge, and the edge is placed at **θ₀ = the centre of the last slat**.
378Land strip 0 is centred on θ = 0, so cutting there would slice a whole strip in
379half across the top and bottom margins; cutting at a slat centre leaves every land
380strip whole and splits only a band of stars, which carries no geography. Same
381reasoning as putting Earth's map edge at the antimeridian. A sightline whose short
382route crosses the edge is drawn as two segments, so the drawn path always matches
383the measured distance.
384
385---
386
387### 1.8 Sightlines: Tower has two horizons
388
389Along the axis the floor is perfectly flat and never falls away, so nothing is ever
390hidden by curvature. **Tower's horizon is haze.** Circumferentially the floor curves
391*up*, so distant land rises into the sky rather than sinking below a line. The two
392directions behave completely differently, and this is one of the most alien facts
393about living there.
394
395Rayleigh transmission from a floor-level observer:
396
397| Distance | Along the axis | Across the interior (overhead) |
398|---|---|---|
399| 26 km | 78 % | 77 % |
400| 50 km | 56 % | 70 % |
401| 100 km | **31 %** | **78 %** |
402| 270 km (far cap from midpoint) | **4 %** — a ghost | — |
403
404Two consequences:
405
406- **The axial horizon closes at 100–150 km.** From the midpoint you cannot see
407 either end cap. Everyone can see 100 km, knows there is more beyond, and cannot
408 resolve it — a different psychology of distance than Earth's 5 km cliff-edge.
409- **The far side of the world is clearer than the ground at the same distance,**
410 because a sightline across the interior rises through thin axis air while one
411 along the floor grinds through full density. It gets *better* with distance: the
412 land directly overhead, 100 km away, is the crispest far object in Tower at 78 %.
413 **Distant geography is best seen by looking up.** People would orient by what is
414 overhead; the ground is the vague part. This inverts the human default.
415
416### 1.9 Water
417
418Tower's hydrology is stranger than its geometry, and most of it follows from one
419fact and one absence.
420
421#### 1.9.1 Coriolis never pushes surface water sideways
422
423The floor's tangent plane is spanned by θ̂ and ẑ, and the spin axis is ẑ. For any
424flow along the surface:
425
426- **along the axis** — `ẑ × ẑ = 0`, no Coriolis force at all;
427- **around the circumference** — `ẑ × θ̂ = −ŝ`, the force is purely radial.
428
429The Coriolis term never has a component *inside* the surface. So **Tower's rivers
430do not curve.** No hemispheres, no Baer's law, no preferred bank erosion, no gyres,
431no cyclones. Every large-scale rotational habit of Earth's water and weather is
432absent, and a meander in Tower is pure flow dynamics with no thumb on the scale.
433
434#### 1.9.2 What it does instead: everything vertical leans
435
436The force goes into the floor rather than across it, so it appears whenever water
437moves up or down. Deflection of a free fall goes as h^1.5:
438
439| Fall | Lands (retrograde) | Lean of the path | Lean at impact |
440|---|---|---|---|
441| 100 m | 4.2 m | 2.4° | 3.6° |
442| 500 m | 47 m | 5.4° | 8.1° |
443| **1,000 m** | **133 m** | **7.6°** | **11.3°** |
444| 2,000 m | 377 m | 10.7° | 15.8° |
445
446Two different angles, and the interior view needs both. The **path** leans by where
447the water lands against how far it fell — the tilt of a waterfall's plume seen
448whole. The **impact** lean is the direction the water is actually moving when it
449arrives, which is what a streak of it is drawn at, and it is half again the other in
450tangent. `src/canon/motion.ts` computes both.
451
452**Rain falls permanently slanted** — a raindrop at terminal velocity sits at a fixed
453**1.47° against the spin**, ~51 m of drift over a 2 km fall, never varying, never
454reversing. It is fixed because drag holds the fall speed constant, so unlike free
455fall the angle does not grow with the drop: rain leans the same 1.5° whatever the
456cloud. Set against a waterfall's 11°, **the waterfall is the compass and the rain is
457not**, which is the opposite of what §2.4 originally assumed (D-034). Rising things lean the opposite way: smoke drifts spinward, rain drifts
458anti-spinward. Every plume and every shower in Tower tilts, and they tilt against
459each other.
460
461The same applies to anything that descends, not just water — see §1.11 on what it
462does to skiing.
463
464Horizontal flow changes *weight* rather than direction (Eötvös): +0.57 % for a
4652 m/s prograde river, negligible hydrologically. It only matters at speed — an
466express train at 100 m/s gains 29 %, and anything moving retrograde at the 700 m/s
467rim speed is stationary in space and therefore weightless.
468
469#### 1.9.3 A perfect cylinder has no slope anywhere
470
471Potential depends only on radius, so **the whole floor is a single equipotential
472surface.** Water on it has no preferred direction: a perfect Tower has no rivers at
473all, forever.
474
475**Every river in Tower exists because the floor was shaped.** There are no
476tectonics and no uplift, so erosion is strictly one-way — a 3 km range wears flat in
477~30 Myr under a wet engineered climate, ~150 Myr under a dry one. Tower's rivers
478are steadily destroying its landscape and the highlands must be rebuilt to keep them
479running. This is D-004's theme again: Tower's rivers are plumbing it chose to
480install and has to keep re-installing.
481
482Two corollaries:
483
484- **No river can circumnavigate.** A closed loop has no net descent.
485- **Lakes curve upward.** Level means constant radius, so across a 30 km lake the
486 far shore rides **2.3 km above your tangent plane** — Earth would hide it 18 m
487 below the horizon. You look *up* at the opposite beach, and water appears to
488 climb away from you.
489
490#### 1.9.4 There is no passive climate at all
491
492**Tower has no latitude** — every point is equidistant from the light — and with the
493hull sealed it has no windows either. Nothing breaks the thermal uniformity. A
494uniform hull radiates at 274 K everywhere, so left alone the world settles into a
495flat calm: no gradient, no wind, no evaporation, no rain, no rivers.
496
497**So every weather system in Tower is deliberate.** Tower makes climate the only way
498left to it — by aiming light. It warms where it wants convection and shades where it
499wants condensation; the hull's uniform loss is the sink. Every cloud, every
500rainfall, every jet stream is something Tower is doing, continuously, on purpose.
501
502This is D-009 arriving at its conclusion. The mirrorlet swarm was already Tower's
503body language; now it is also its lungs and its weather. There is no autonomic
504layer underneath. **If Tower's attention ever lapses, the rain stops.**
505
506Costs, for scale against a 54.3 TW budget:
507
508| | | |
509|---|---|---|
510| Earth-like rainfall, 1,000 mm/yr | **12.2 TW** | **22.4 %** — Earth spends the same fraction |
511| Recirculating all runoff (1,792 m³/s) against 500 m | 8.8 GW | 0.016 % |
512
513#### 1.9.5 Rivers are a closed, pumped circulation
514
515With no natural cycle and no natural slope, a Tower river is a **loop**: a headwater
516reservoir, a shaped descent through the landscape, a lake at the bottom, and a lift
517back to the top. Source and sink are the same system.
518
519Two ways to close the loop, and they give completely different rivers:
520
521- **The pump outfall.** A river begins at a machine. Walk to the source of any
522 river and find a wall of water coming out of a structure — not a spring, an
523 outlet. Costs a rounding error (above).
524- **The made cloud.** Tower evaporates the lake with aimed light and condenses it
525 over the highlands, so rain falls exactly where the river should start. No
526 machinery: the swarm is the pump. Costs the 22.4 % above, and buys real weather
527 with it.
528
529Canon uses **both** — made weather for the world's general hydrology, pumps for
530watercourses Tower wants under precise control.
531
532Two consequences of the sealed hull:
533
534- **A river can circle the world.** The surface is one unbroken sheet, so a channel
535 can run the full 314 km circumference and close on itself — a lazy river returning
536 to its own source. Gravity cannot drive a closed loop, so it is pumped.
537- **The water inventory is conserved and exactly known.** Nothing evaporates to
538 space. Tower knows how much water it has, to the litre, forever.
539
540Lifting is also slightly cheaper than on Earth, since gravity falls off with height:
5411 % cheaper at 1 km, 5 % at 5 km, 25 % at 25 km.
542
543### 1.10 Slat orientation — RESOLVED: none
544
545Axial strips versus rings was weighed at length (D-016) and answered by removing
546slats entirely (D-017). The comparison is kept in D-016 because it established what
547the choice *cost*, and because the reasoning — that slat layout sets the shape of
548Tower's countries, its climate map and its astronomy all at once — is what made
549"none" a real option rather than an absence.
550
551### 1.11 The world as built
552
553Authored geography lives in **`content/geography.json`** — the source of truth — and
554`npm run terrain` renders it. Names are provisional. Tower is laid out in **belts
555along the axis**, which is the natural grain of an engineered climate (§1.9.4):
556
557| z | | |
558|---|---|---|
559| 0–42 km | **The Sunward Sea** | ring ocean at the foot of the sun cap |
560| 55–140 km | **the range** | Westwall, The Sisters, **Snowcrown** (4,300 m), Eastwall — the named high points of **The Girdle**, which rings the world at z 90 km (D-051) |
561| 148–218 km | **The Dry Reach** | desert **ringing the world**, 22,000 km², 13% of the surface |
562| 176/190/203 km | **three ridges** | ringing, concentric — and **The Narrows** is the only breach in all three |
563| 214–430 km | **Greatwood** | forest belt |
564| 248–402 km | **The Deep** | 154 × 32 km sea, long down the axis and narrow around |
565| 270 km | **The Capital / The Spindle** | axial midpoint, on The Deep's antispinward shore |
566| 496–540 km | **The Deepward Sea** | ring ocean at the foot of the far cap |
567
568#### Why the desert rings
569
570**On a cylinder you cannot go around a band.** Every desert on Earth can be
571circumnavigated; a ringed one cannot. It is an absolute barrier across the world's
572waist, and with the three ridges ringing too it becomes three concentric walls.
573
574#### The drainage, and why it keeps the chokepoint
575
576Four rivers come off the range — Westwall Water, Sisters Water, Eastwall Water and
577The Long Water. On Earth most drainages **do not** cut through a rising ridge; they
578are defeated and diverted, and only an *antecedent* river with enough power keeps
579its course. So three of the four are turned by First Ridge, run **along its front**
580gathering each other, and leave with the fourth through the single gap.
581
582- **The Narrows carries the entire world's runoff** — ~392 m³/s off a 9,800 km²
583 range, lifted 1,780 m for 6.9 GW (0.013% of budget).
584- The ridge-front reaches are **the only circumferential water in Tower**, and
585 weigh fractionally more or less for it (§1.9.2). Everything else runs axially,
586 where Coriolis is exactly zero.
587- Whoever holds The Narrows holds the axis of the world. The Capital sits behind it.
588
589#### The Deep is oriented for the view
590
591Long down the axis and narrow around it, so you cross it the **short** way — around
592θ, where the floor curves up. From the Capital the far shore is 32 km away and
593stands **2.6 km above eye level**. Crossing it lengthwise instead would be dead
594flat. The orientation is the whole point.
595
596It is also the world's flywheel: 19× the diurnal heat storage of bare ground, and
5975.9 days at full power to move its temperature one kelvin. Tower still supplies
598every joule (§1.9.4), but the world now coasts for about a week rather than
599stopping the moment attention lapses.
600
601#### The cap seas are not designed
602
603Gravity on an end cap points radially outward — *tangent* to the cap. Nothing rests
604there; water runs down to the rim and pools. **Both ring oceans exist whether anyone
605planned them or not**, each with a 314 km shoreline and a 50 km cliff standing
606behind it. The only windows in the world are at their feet (§1.4).
607
608#### Skiing, because it is a different sport here
609
610Level motion feels no Coriolis (§1.9.1) but a descending skier has radial velocity,
611and that does deflect:
612
613- **Down the axis:** a steady sideways push, always antispinward — 1.5% of g at
614 15 m/s on a 20° slope, 6.4% at 35 m/s on 40°.
615- **Around the cylinder:** you get heavier or lighter. 8.6% at 30 m/s, 11.4% at 40.
616
617So a **retrograde run gets lighter the faster you go**, which is self-reinforcing,
618while a prograde run grips harder as it accelerates. Every slope in Tower has a
619handedness. No Earth mountain does. Settlements sit at the tarns — Sisters Station,
620Hollow Station — around 2,100 m, with the runs above them.
621
622#### Open questions
623
624- **The Spindle's height.** 3.2 km is a placeholder; an object dropped from its top
625 lands ~760 m antispinward of its base.
626- **z 430–496 km** is unauthored. The circumference outside the named peaks is no
627 longer empty — The Girdle carries the range round the whole 314 km — but it is
628 unwalked: peaks with no names, and no rivers drawn off them yet.
629
630## 2. Application architecture
631
632### 2.1 Stack
633
634- **Vite** + **TypeScript** (strict), no framework — the app is three canvases and
635 a control panel, and a framework would not earn its weight.
636- **One layout breakpoint**, at 720 px: above it the panel is a column beside the
637 world, below it a drawer over it (D-043). The world is a full-bleed canvas in
638 both, because all three views are drag-to-look and a scrolling page would be
639 fighting them for every touch.
640- **Three.js** for the exterior and interior 3D views.
641- **Canvas 2D** for the map view.
642- **GitLab CI → GitLab Pages**, publishing `dist/` as `static/`.
643
644### 2.2 Module layout
645
646```
647src/
648 canon/
649 constants.ts single source of truth for every number in §1
650 geometry.ts (θ,z) <-> 3D, slat layout, map <-> surface
651 atmosphere.ts the rotational density profile and its extinction (§1.5)
652 motion.ts how things fall in the rotating frame (§1.9.2) — the only
653 evidence of the spin anywhere but the far cap window
654 views/
655 palette.ts one colour per place kind, shared by map, list and editor
656 raster.ts what npm run terrain wrote: grid, and what white means
657 world/
658 schema.ts world.json types + validation
659 store.ts places CRUD, localStorage drafts, JSON import/export
660 instruments.ts sightline, viewshed, lighting probe, travel (§3.3)
661 state/
662 store.ts selected point, time-of-day, spin phase, view mode, writer flag
663 views/
664 exterior.ts Three.js: hull, caps, collector, beam, spin, point picker
665 map.ts Canvas 2D: unrolled surface, slats, terminator, point picker
666 interior.ts Three.js: shell geometry, the haze shader of §1.5, beam, rain
667 ui/
668 app.ts the whole panel: tools, editor, readouts, view switching
669 scales.ts slider mappings — kept out of views/ so the panel can label
670 the eye-height slider without pulling in Three.js
671 main.ts
672
673tools/ node-only, never bundled; plain .mjs with no build step
674 terrain.mjs renders content/geography.json into static/ (§1.11)
675 png.mjs minimal PNG encoder — zlib is its only dependency
676 noise.mjs fbm and ridged noise for the terrain relief
677 screenshots.mjs drives the running application in a headless browser and
678 photographs it into docs/screenshots/ (D-042)
679```
680
681`canon/constants.ts` is the spine. Every derived figure — period, rim speed, land
682area, slat width — is *computed* from radius, length, slat count and target land
683area, never hard-coded. Changing the radius changes the whole app coherently.
684
685### 2.3 State
686
687One small observable store. Views subscribe; nothing owns anything else.
688
689```ts
690type TowerState = {
691 point: { theta: number; z: number } | null // the picked location
692 tod: number // 0..1, position in the diffuser day cycle
693 brightness: number // W/m^2 mean, 30..320 -- the diffuser output setting
694 spinPhase: number // 0..2pi, rotation for star motion
695 spinning: boolean
696 view: 'exterior' | 'map' | 'interior'
697 writer: boolean // ?writer=1 -- a UI mode, not a security boundary
698 probe: { from: SurfacePoint; to: SurfacePoint } | null
699}
700```
701
702The exterior and map pickers both write `point`; the interior view reads it. That
703is the entire interaction loop.
704
705### 2.4 The exterior view
706
707Scene units are kilometres, so the code reads in canon numbers. Tower's axis lies
708along world Z with the sun cap at z = 0, which puts a canon surface point at
709`(R cos θ, R sin θ, z)` in the hull's own frame. The hull spins about Z and carries
710that frame with it, so **picking resolves the ray hit back through
711`worldToLocal`** — otherwise every point picked off a turning hull would be wrong by
712the spin phase.
713
714Two deliberate departures from physics, both reading aids of the same kind as the
715map's hillshade:
716
717- **Fill lighting.** Real sunlight here runs parallel to the axis, so Tower's flank
718 is edge-on to it and renders very nearly black — accurate and useless. Two fill
719 lights lift the hull enough to read its shape.
720- **A visible beam.** In vacuum there is nothing between collector and cap to
721 scatter light, so the converging beam would not be visible at all. It is drawn
722 as rays because it is the thing the view is about.
723
724Everything in the scene is captioned — collector, beam, both caps — with screen-space
725labels. A pale disc and a cone of light are not self-explanatory, and the collector
726is the least intuitive object in Tower: it is larger than the world it feeds.
727
728The default camera frames the whole system rather than Tower alone: the collector
729is 244 km across and flies 320 km ahead, and it is the larger object.
730
731**The hull has two readings, and the view switches between them** (D-047). **True**
732is the outer skin: bare structure, the checkered sun cap, and the glazed far cap.
733**X-ray** wraps the terrain raster onto the outside instead — from outside Tower is
734structure, so what that texture shows is what is *inside*, which makes it a diagram
735and not a view. Both are worth having and they are not the same claim, so the
736control is a two-way switch rather than a checkbox.
737
738The wall is drawn as two meshes rather than one double-sided one, because its two
739faces show different things: the outer skin changes with the mode, and the inner
740surface is always the land. Since the far cap became a window (D-045) that inner
741surface is genuinely visible from outside — look in through the glass in true mode
742and the world is really there, lit and 540 km deep. It is the only line of sight
743into Tower that is not a projection. Three's cylinder runs u around and v along, while the raster is the other
744way round, so the UVs are rewritten from the original attribute rather than derived
745from vertex positions — the seam vertices are duplicated, and deriving an angle from
746them smears one column of triangles across the whole image.
747
748**The camera position persists** across reloads, alongside the active view, so
749returning to the page returns to the vantage you left. Both end caps are places in
750their own right, so the view can frame them: a cap's marker sits on the **axis**,
751because a cap is a disc across the end and a point on its rim would ride round the
752edge as Tower turns.
753
754Markers are scaled per frame to hold a roughly constant size on screen. A 4 km dot
755is legible from 200 km and sub-pixel from the 1,200 km of the default view, which is
756to say the places would simply not be there.
757
758### 2.4 The interior view — built
759
760Scope held: **real geometry, simple ground.**
761
762Real: the shell is the actual cylinder, curving up on both sides and closing
763overhead, displaced by `terrain-height.png` and painted with `terrain-color.png`.
764**Stars only through the far cap** — the wall is sealed (§1.4), so for 539 of the
765540 km the sky is land and light. The far cap is glazed (D-045) and the sky beyond
766it is sampled by view direction in an azimuthal-equidistant projection about the
767spin axis, which makes the pinwheel fall out of the projection rather than being
768animated into it: azimuth plus spin phase, one turn every 7 min 29 s, and the
769point on the axis genuinely motionless.
770
771Simple: the ground is the raster plus a little procedural grain in the near field,
772not modelled scenery. No buildings, no vegetation meshes. Cells are 0.7 km and
773texels 264 m, so relief a valley away is real and the ground underfoot is not.
774Detailed procedural scenery stays deferred.
775
776**Haze is the shader, and it is integrated rather than faked.** Every fragment
777samples the rotational density profile 24 times along the ray to the camera and
778extinguishes per channel — red survives twice as far as green, blue half as far,
779which is what makes distance blue rather than grey. From the floor it reproduces
780§1.8 from the inside: 78% straight up against 31% for the same 100 km along the
781ground, printed in the readout so the claim can be checked rather than believed.
782The airlight the haze adds is *neutral*; tinting it blue double-counts the
783wavelength dependence and turns even the desert mauve (D-034).
784
785**Nothing inside the scene rotates**, because the observer, the ground and the air
786all co-rotate. What falls carries the spin, and §1.9.2 is lopsided about how: rain
787leans a fixed 1.5° whatever the cloud, because drag pins its speed, while only free
788fall keeps accelerating and so keeps leaning. **The waterfall is the compass; the
789rain is barely a hint.** Rain is no longer drawn (D-049) — 1.5° is not a picture,
790and the pinwheel below does the job it was standing in for. The physics stays in
791`canon/motion.ts` and stays tested; it was only ever the rendering that could not
792carry it.
793
794**The one thing that does turn is outside.** The sky through the caps does not
795co-rotate, so it wheels once every 7 min 29 s about the motionless star on the axis
796(D-045). It is by a wide margin the plainest evidence of the spin in the view, and
797it is the only evidence left now that the rain is gone. Both caps are windows
798(D-050), so it can be had looking either way along the axis — deepward into empty
799space, or sunward past the black disc of the collector.
800
801The observer stands on the terrain, which means the height raster is read back onto
802the CPU and sampled against the mesh's own cell corners — the GPU cannot be asked
803where the ground is (D-035).
804
805Instruments in the view: eye height from 1.7 m to 25 km with the local gravity
806beside it, the five canon illumination settings of §1.3, the field of view as a
807pair of binoculars, and captions on every place still visible through the haze.
808Selecting a place walks the observer to it (D-038) — the haze horizon closes at
809100–150 km, so turning to face something usually just points at haze.
810
811The caps are no longer the same object. **The sun cap is checkered** (D-041) —
812polar, six rings, cells about 8 km. **The far cap is glazed** (D-045), and the
813checker survives on it as the window's mullions: the same tessellation at the same
814pitch, so it is still the only object in the world with a known size and still
815doubles as a scale for judging distance, now read against sky rather than plate.
816Both patterns are shared with the exterior view.
817
818The far cap's glazing is set a kilometre into its own frame, so from inside there is
819a **1 km reveal** around it. That is the only place the wall depth of D-044 can be
820seen from within the world, which is why it is the only place it is drawn.
821
822Not modelled: water has no surface. Lakes and seas are painted in the raster and cut
823into the shell as basins, so standing in one puts you on its floor.
824
825---
826
827## 3. Writer mode and the world file
828
829The app is an instrument for writing the novel as much as a thing to look at. It
830must answer questions like *can the far face be seen from the midpoint?*, *where
831does a central embassy go?*, *can a lake overhang?* — and let their answers be
832placed, named and kept.
833
834### 3.1 Two modes over one data file
835
836| | Reader (default) | Writer (`?writer=1`) |
837|---|---|---|
838| World content | committed `world.json`, read-only | editable, drafts in `localStorage` |
839| Instruments (§3.3) | sightline probe only | all |
840| Output | permalinks to a point or place | **Export JSON** for the author to commit |
841| Panel | read-only detail card | full editor, canon controls, import/export |
842
843There is no backend — GitLab Pages is static. The loop is: the author edits in the
844browser, exports `world.json`, commits it, and the published site serves it. Simple,
845versioned in git alongside the prose, and diffable.
846
847**Writer mode is a UI mode, not a security boundary.** Anyone may set `?writer=1`;
848they can only edit their own local copy, which persists nowhere and reaches nobody.
849This is fine, and arguably good — a reader who finds it gets a sandbox. It must not
850be mistaken for access control.
851
852### 3.2 The world file
853
854```jsonc
855{
856 "version": 1,
857 "places": [{
858 "id": "hallow-crossing", // permalink target; see below
859 "name": "Hallow Crossing",
860 "kind": "city|embassy|lake|region|landmark|note",
861 "geometry": { "type": "point", "theta": 1.9635, "z": 270000 },
862 // or { "type": "polygon", "points": [[theta,z], ...] } for lakes, regions
863 "blurb": "public description, shown to readers",
864 "notes": "the author's working notes — NEVER shipped",
865 "public": true // false = not ready to exist publicly
866 }]
867}
868```
869
870**Two text fields, deliberately separate.** `blurb` is written for readers and
871ships; `notes` is the author's working thinking and never leaves the machine except
872in a backup. One field with a flag would have made every note a publication
873accident waiting to happen.
874
875**Ids follow the name until pinned.** An id is a permalink target and must be
876stable once published, but during world-building names churn constantly and a file
877full of `new-city-7` is unreadable. So the id tracks the name while it still
878matches it, and editing the id field freezes it for good. The editor shows the id
879for exactly this reason.
880
881Coordinates are canon (θ radians, z metres, §1.7) — never map pixels, so the file
882survives any change to how the map is drawn.
883
884**The `public` flag is a privacy trap worth naming.** Working notes ("embassy here?
885check sightline to the cap") must not ship to readers. But a `world.json` committed
886to a public repository is public regardless of any flag in it. So export writes two
887files: **`world.json`** (public entries only, committed) and
888**`world.private.json`** (everything, gitignored by default). Whether private notes
889should nonetheless be version-controlled — in a private repo, or a second one — is
890the author's call and is deliberately unresolved.
891
892### 3.3 Instruments
893
894The measuring tools are the real substance of writer mode. Each answers a question
895the novel actually raised:
896
897- **Sightline probe.** Pick two points; get surface distance, straight-line
898 distance, optical depth, transmission, and a plain verdict (*crisp / hazy / ghost
899 / invisible*). This is the tool that answered §1.8. Available to readers too — it
900 is the single most illustrative thing in the app.
901- **Viewshed overlay.** From a selected point, shade the whole map by transmission.
902 It renders the axis-versus-overhead asymmetry as one picture, which is worth more
903 than the table in §1.8.
904- **Lighting probe.** At a point, illumination across the day cycle at the current
905 brightness setting (§1.3) — for writing a scene at a specific hour.
906- **Travel.** Surface distance and journey time between points at chosen speeds,
907 including whether the route crosses a slat.
908- **Sky-at-a-time.** Star field, beam position and Earth transits for a given point
909 and moment, so a described sky is a correct sky.
910
911### 3.4 What readers get
912
913The public link is the finished map: embassies, towns, lakes, named regions — the
914permanent things, behaving like any map application. Plus the exterior view, the
915interior view from any point, and permalinks so a reader can be handed a place and
916a moment. Reading the world, not editing it.
917
918## 4. Phases
919
9201. **Design** — this document and `decisions.md`. ← current
9212. **Scaffold** — Vite/TS/Three, CI to Pages, `canon/` implemented and unit-tested.
9223. **Exterior** — ✅ hull, caps, collector, beam, spin, and hull point picking.
9234. **Map** — unrolled surface, slat rendering, picking, sync with exterior.
9245. **Interior** — ✅ shell geometry, the haze shader, the beam, rain, eye height,
925 and the five illumination settings. Stars, but only through the far cap window.
9266. **Writer mode** — ✅ *built ahead of 3–5, at the author's request, because the
927 world needs developing before there is anything to render.* Map view, place
928 editing for all thirteen kinds, points/polylines/polygons, localStorage
929 autosave, backup and static exports, import, and the sightline probe.
9307. **Content pipeline and reader mode** — ✅ `content/geography.json` +
931 `npm run terrain` (D-019); the rendered terrain drawn under the map; reader and
932 writer modes (D-011); permalinks (D-010).
9338. **Polish** — mobile ✅ (the sidebar is a drawer below 720 px, D-043) and a
934 screenshot tour that photographs all ten views through the UI, D-042.
935 Remaining: transitions, performance.
936
937All five view phases are built. Phase 2's `canon/` landed with phase 6, since the
938map could not be drawn without it.
939
940**Shareable permalinks are implemented** (phase 7) — the app has
941readers, and "stand here and look at this" is the whole reason it exists as a
942companion piece. Named locations from the novel should be markable on the map for
943the same reason.
944
945Later, explicitly out of scope for now: procedural scenery, settlements, weather
946systems.