A curated transcript of the conversation (with Claude Code) that produced the 21st-century orrery for tao-web — a first-person sandbox for frames of reference and scale, from the first sketch to launch.
How to read this. The aim is to convey the process, not to reproduce the raw log:
- Terence's messages are shown mostly verbatim. The earliest ones, and a few short clarifications, are condensed from session summaries (the original text had scrolled out of the log) — marked (condensed).
- Claude's replies — almost entirely edits to two files,
orrery.js(a DOM-free astronomy/geometry core) andorrery.html(the hand-rolled WebGL app) — are replaced by short italic summaries of what changed. The diffs are omitted. - Unrelated threads from the same sessions (other website edits, reboots) are left out.
The whole thing was built incrementally over many sittings and kept uncommitted for local testing throughout. The geometry and astronomy were checked with small headless Node unit tests (the logic core) plus a DOM-shim, stub-WebGL "smoke" test for the UI wiring — by launch, ~93 and ~157 checks respectively.
1. The idea: one honest number in a sea of exaggeration
Terence (condensed):
I'd like a "21st-century orrery" — not the brass-gears kind, but a sandbox for frames of reference and scale. The core conceit: stand somewhere on a to-scale spherical Earth and raise your eye height, from a person up to orbit, and watch the horizon dip and curve. That horizon dip is the one thing that should be genuinely to scale; almost everything else (planet sizes, the Moon's distance) will have to be exaggerated to be visible at all. Let's reconstruct a staged plan and start with a testable math core.
Claude reconstructed a staged roadmap (a DOM-free model → a first-person WebGL scene → a moving sky → frames of reference → publication) and argued for hand-rolling WebGL rather than pulling in a 3-D library, to keep the app self-contained (no network, no CDN — the site's standing rule). It then built Stage 0: orrery.js, an idealized model (circular orbits, constant rates, Sun and Moon on the ecliptic, a fixed 23.44° tilt), with the one to-scale quantity — horizonDip(height) — validated against known values (1.7 m → 0.042°, an airliner → 3.2°, the ISS → 19.7°).
2. Standing on a ball: the first-person scene
Terence (condensed): build the first-person view and the altitude scrub.
Claude built the WebGL scene, which immediately ran into two problems worth recording. First, a 1.7 m person on a 6371 km sphere overflows float32, so vertices are computed camera-relative in double precision and only then handed to the GPU. Second, a uniformly tessellated sphere renders the near ground as flat facets — so the mesh uses log-spaced polar rings, dense right under the observer, so the horizon curves correctly at every height. The camera auto-pitches by the dip so the horizon stays centred, and a dashed eye-level line sits above the dropping sea-horizon.
Terence (condensed, across several exchanges):
Let's populate the coast. Put things at every bearing and a range of scales — a person, a dog, a house, the Eiffel Tower, an airplane overhead, a container ship out to sea, a distant mountain island. Hovering an object should give a telescope zoom. And the ship should sink hull-first below the horizon as you lower your eye — that's the money shot.
Claude added the object system (boxes and cones placed by bearing/distance, camera-relative), hover tooltips, and the telescope inset (a second render into a scissored circular viewport). The "sinking ship" falls out for free: the sea, drawn as part of the sphere, occludes the hull through the depth buffer.
3. A sky that moves
Terence (condensed): make the Sun move; add day/night, shadows, and the first-person body.
Claude wired the Sun to the model, added play/pause with a speed control, a full-screen sky shader (day/night gradient, a glow toward the Sun, twilight, the Sun's disc), flat projected shadows, and the observer's own stick-figure body at their feet — scaled to eye height, so you become a giant as you climb. More objects joined the coast: a hot-air balloon, a hill, a road and car, a cloud, and — wading so the sea hides his legs — Godzilla.
Terence:
Orrery is going great! More feature requests: (a) an option for objects below the Earth to be visible. (b) an option to keep perspective locked (stabilized) by default to the fixed stars, so that it is the ground that moves (this makes the arrow keys act in unintuitive ways now that "ground" is at a different angle from "down", but this disorientation is part of the point).
Claude added see-through Earth (a translucent globe drawn last, so below-horizon objects show through) and lock-to-stars (the camera counter-rotates about the celestial pole, so the stars hold still and the ground wheels beneath you). Along the way came night stars and constellations, the ecliptic, and the Moon — drawn as a small Sun-lit sphere, so its phase falls out of the lighting geometry rather than being painted on.
Terence:
I think the simplified wide FOV works great.
4. Cosmic view: dropping the Earth's spin
Terence:
Another feature is a little tricky to explain, so let's make sure we're on the same page before implementing. I'd like a "cosmic view" in which all terrestrial objects (including one's body) disappear, the Earth becomes a featureless sphere, and one is no longer bound by the rotation of the Earth, being automatically locked to the stars. There's no longer a horizon to reference, so one pans with the arrow keys to pitch and yaw. In this view one should accelerate to much greater speeds (1 day/sec, 1 month/sec…). Right now it isn't interesting because only the Sun and Moon move — but if we add planets it becomes an orrery seen from the Earth's location (ignoring the Earth's spin). Leaving the view should snap the orientation back, and cap the speed again.
Claude agreed the plan, then asked a few design questions (add planets now? how to render the see-through Earth? discrete or continuous speeds?). Terence chose planets now, a see-through globe, and discrete round-number speed steps. Claude added the naked-eye planets to the model (Kepler elements → heliocentric → geocentric → alt/az — enough that Mercury and Venus stay near the Sun and Mars visibly loops), then built cosmic view: terrestrial objects fade out, the Earth becomes a plain translucent sphere, sidereal time freezes so the stars lock, and time can run up to a year per second.
Terence:
A fadeout transition when going from one mode to another would be cool — objects fade out, the Earth loses its colour. (Though when snapping back you can't do that, because the orientation will almost certainly have changed.)
Added: a smooth fade in, an instant snap on exit.
Terence:
I'm not sure how to execute pan-by-drag in cosmic view mathematically — we'd basically need dragging in spherical coordinates. Presumably there's a standard solution?… parallel transport perhaps?
Exactly. Claude replaced the yaw/pitch angles with a free camera basis rotated incrementally about its own axes (Rodrigues rotations) — parallel transport, no gimbal lock — so dragging feels natural from any orientation.
Terence:
It might be amusing to have a "Pluto is a planet" checkbox, to keep both sides of the debate happy.
Added, opt-in.
5. The God's-eye orrery
Terence:
I'd like to implement the "God's eye" orrery as a separate screen, below the main viewpane so one can see both at once (especially in fast cosmic mode). A perfectly to-scale depiction would make the planets impossible to see, so they'll have to be exaggerated. The outer planets won't fit by default, but with pan and zoom one could navigate to them. A full 3-D view may be too tricky; I'm thinking of a planar top-down view of the solar-system plane. Any thoughts on the best design for high visual impact while staying somewhat scientifically accurate?
Claude proposed the honesty split that governs the whole pane: angular positions and orbit shapes come straight from the model (so conjunctions and elongations line up with the sky above), while only the body sizes and the Moon's orbital radius are exaggerated. Since a top-down view can't show a real crescent, the Moon and Earth get Sun-facing terminators instead, illustrating the cause of the phases. For the 100× range from Mercury to Pluto, Terence chose a hybrid scale — a button toggling "true distance" (linear, zoom/pan) against "compressed" (logarithmic, everything at once). It renders on its own 2-D canvas and auto-opens in cosmic view.
6. The telescope gets serious
Terence:
One can store the diameters of the planets to show up in the telescope. If one can give Saturn some rings and Jupiter four faint moons (even better if they orbit with their correct orbital periods), that would be a nice easter egg (even if the moons aren't themselves named as objects). This is for the telescope view.
Claude made the telescope draw a magnified, Sun-lit planet disc (so inner planets show phases), Saturn's rings, and Jupiter's four Galilean moons orbiting at their true relative periods.
Terence:
In the telescope, the Moon is labeled as Venus and is dark. (Giving it a red spot would be nice.)
Two bugs. The "Venus" label was a floating sky-label overlapping the telescope inset; the "dark" was a near-new Moon near the Sun. Claude taught the labels to avoid the inset and gave the Moon a touch of earthshine — and, as requested, gave Jupiter its Great Red Spot, carried around by the planet's ~10-hour rotation.
Terence:
Jupiter is displayed as a black disk instead of orange.
This one was real. Claude had been lighting planets by the Sun's direction as seen from Earth, which is fine for inner planets but wrong for the outer ones — Jupiter, never far from opposition, was being lit on its far side. The fix computes the true phase angle (Sun–planet–Earth) so outer planets read full and Venus shows a proper crescent.
Terence:
And Saturn looks like an annulus. I think the rings should be more aligned with the ecliptic, and the planet needs to be a yellowish colour.
The rings had been tilted a fixed amount off the view axis, so they read face-on. Claude laid them in the ecliptic plane (so they appear as a shallow tilted ellipse) and warmed the planet to gold.
Terence:
Is the Moon's angular width accurate? It seems a lot smaller than the Sun.
The Moon was right (~0.52°); the Sun's disc was drawn about twice too large. Claude shrank it to the true ~0.53°, so the two now match — which is, of course, why eclipses work.
7. A livelier world
A long tail of requests turned the scene from a demo into a place.
Terence:
Right now the initial state is 1 day/sec, paused. Can we start at a gentler rate, playing? … The mountain either disappears completely below about 10 m of eye height, or is fully visible; I wanted to see an intermediate dip.
Claude started the app gently animated, and traced the mountain bug to the far clip plane — at low eye heights it sat closer than the 44 km mountain, clipping it whole. Pushing it out let the mountain's base dip below the horizon like everything else.
Terence:
For additional objects, one can add the Magellanic clouds, a geostationary satellite, and the ISS. (The latter two would be considered "terrestrial" for the purposes of cosmic view, otherwise they would be whizzing around like crazy.) … There is a bare sector between the cloud and the Eiffel tower that looks boring. Can one put a tree there? … I'm aiming for one representative object of a given type and scale rather than a lot of very similar objects. … Maybe a kite, attached by a string to the human? The string does not need to be an object or cast a shadow. … We have one example of a cloud (cumulus). Maybe make one instance each of the other common types (nimbus, cirrus) and spread them around, so cloud identification is a minor educational benefit.
Claude added a tree, a lighthouse, and a small sailboat; the Magellanic Clouds as faint deep-sky smudges (below the horizon from 40°N, so they show only in see-through or cosmic view); a geostationary satellite (fixed due south) and the ISS (properly topocentric, so it actually rises and sets), both hidden in cosmic view; a kite on a drawn tether to the person; and cirrus and cumulonimbus clouds to go with the cumulus.
Terence:
The storm cloud has the right colour, but the shape looks like a Greek pillar with sharp angles. Is there some way to make it more "cloud" shaped?
Rebuilt from rounded dome billows with a spreading anvil, instead of boxes.
Terence:
When see-through Earth is activated, the telescope should be able to see celestial objects below the Earth (and label them). Relatedly, an option to label the terrestrial objects by name in the main view. … Object labels can also make the Sun and Moon labeled.
Both added.
8. The Moon, the road, and a 6000-km shadow
Terence:
The Moon always seems to be rendered as black in the view, even when in the full-moon phase.
Claude checked the lighting numerically — a full Moon above the horizon renders at essentially full brightness, so the maths was fine. The culprit was the default start (the model's epoch is a new Moon at noon): a new Moon's unlit face was showing as a black disc in daylight. Claude made a thin/new Moon fade into the bright sky instead.
Terence:
Can one set the starting time to have a full moon instead, so one can immediately see a bright moon without waiting half a month?
A pleasant impossibility: a full Moon is opposite the Sun, so it's only ever up at night — a literal full Moon would darken the whole daytime scene. Claude searched the model for a compromise and set the start to a fat waxing gibbous, high in the afternoon: an unmistakably bright Moon with the coast still in daylight and the Sun low for long shadows.
Terence:
The car/road/city lies directly due south, which collides with the S compass line. Maybe rotate them slightly SW instead.
Rotated — which then exposed that the road was built from axis-aligned tiles: once turned, they no longer joined up.
Each road strip has been rotated, but the road is no longer connected. Can you line up the strips to form a single line, with the city at the end and the car on the road at about its current distance?
Claude rebuilt the road as one continuous ribbon laid along its bearing (with a dashed centre line), so it stays a single connected line at any heading, curving with the Earth to the city at its far end.
Terence:
When one is extremely large, one's shadow actually overflows the Earth's surface. Can one truncate shadows to lie within the Earth's visible sphere? In principle one could correct for the curvature, but that's a tricky nonlinear calculation and I'm willing to sacrifice a bit of realism (especially since we're dealing with a 6000 km-tall giant here).
Claude dropped each shadow vertex onto the globe (renormalized to the surface), so a giant's shadow wraps onto the visible cap and everything past the horizon is clipped by the Earth through the depth buffer — crude, but it keeps the shadow on the planet.
9. Launch
Terence:
I think we are about ready to launch the app as an "in progress" state. Can you update the html page, add a link from the applets page, and run audits to see if there's anything major left to do?
Claude refreshed the intro, added an Astronomy entry to the catalogue, and ran the audits: self-contained (no network, strict content-security policy) and well-behaved (it touches nothing outside its own box) — both confirmed. A code review turned up one launch-worthy issue: shader failures were silent, so a GPU lacking high-precision fragment maths would show a blank canvas. Claude added compile/link checks (falling back to a plain "couldn't start WebGL" message) and a portable precision fallback, fixed a mislabelled telescope magnification, and left the rest — chiefly a per-frame allocation pass — as known work for a "work in progress". And so it launched.
Built with Claude Code. The app's source is MIT-licensed; this transcript and the app's content are © Terence Tao.