Chapter 8 · Section 5
Wells Drawn
The BPT law
BPT Part 2.4 (Event Horizons and Null Wells) and Part 2.7 (The Null Well: Collapse as Creation) make a well a Null Well, a black hole whose core is where a new dimension opens; BPT Part 2.9 gives its size, the Stellar Null Well Condition r▣ = 2·G·M▣/c². BPT Part 3.12 (Ripples, Spin, and the Whirling Disks) explains why gas round a well whirls: it "cannot radiate its angular momentum, so it falls inward while keeping its spin, turns faster as it shrinks, and settles where its spin holds it up: a rotating disk", turning at the Disk Rotation v⊚ = √(G·M/R).
BPT Part 3.14 (Galaxies: the Wells and the Stars Around Them) says how a well is known and shown. A feeding well's light is set against its Eddington Luminosity: "A well feeding near this limit is a quasar; one feeding at a small part of it is a Seyfert galaxy", and the Eddington Ratio of a Well (G) λ_E makes "a Seyfert from a hundredth, a quasar from a tenth". Its Game's Reading is the drawing's specification: "The simulation draws each well at its true horizon, a dark point too small to see from afar, and shows it by the stars gathered round it; a tap anywhere in a galaxy selects its well ... A central well that feeds fast lights as a quasar, a blazing core with two jets along its spin axis, standing up from the torus's surface, and a weaker one as a Seyfert glow." Wells are numbered by rank, heaviest first, "Well #1, the universe's Alpha Well, marked through its whole life"; "A merger that carries any well past an eighth of its universe is announced as an Ascendant Well"; "Ascendant Wells are named on screen and Well #1 wears a gold hoop; a well is drawn only when it can be seen, feeding, at a galaxy's heart, Ascendant or first, and the rest keep their place and their lives without being drawn."
BPT Part 3.13 makes the waves of a merger the space layer at work: "Gravitational waves are the working of the space layer ... space itself rippling as the masses on it move." Two orbiting masses give it the Gravitational-Wave Power P_GW = (32/5)·G⁴·m₁²·m₂²·(m₁ + m₂)/(c⁵·a⁵), and in the game's reading of that Part "a ring spreads across the skin from the merger".
The established physics
A black hole emits no light of its own; it is seen by what orbits and falls into it. A well's luminosity against its Eddington limit (Eddington 1926), the Eddington ratio, separates quiet nuclei from Seyferts and quasars, and fast feeding launches jets along the spin axis. A merger's gravitational wave runs out at light speed and rings down after its peak (Abbott et al. 2016). The thresholds the game uses, 0.01 and 0.1 of Eddington, are set in app.js (Chapter 3).
The game's math
setWells(list) scene3d.js:1461 draws the wells. The Proto Wells (the data wells) go to the Proto layer of Part 8.6. Of the rest, sorted with the stellar wells last:
Which are drawn. A well is drawn when it can be seen: feeding (Eddington ratio ≥ 0.01), at the heart of a drawn galaxy, Ascendant, or Well #1. A dark well, quiet and alone, and a quiet stellar well get no mesh; they are kept in _darkWells so a tap still finds them (scene3d.js:1497–1499). Every well that can be seen is drawn, whatever their number (since 2026-10-29).
The size of a mark. With the cell width cellW = 2π·(HOLE + TUBE·scale)/cols (scene3d.js:1484),
mark = (0.35 if inside a drawn galaxy, else 1) · (0.006 + 0.0025·min(10, log₂(1 + mass)))
true = horizon · cellW (its horizon to scale, when the well reports one)
size = max(mark, true)
A horizon wider than its mark is laid flat on the skin as a black disk of radius true, with the mark on it (scene3d.js:1505, 1535). Every physical well has a black core at least a share of the torus's span (HOLE + 2·TUBE·scale): 0.03 for Well #1, 0.026 for an Ascendant Well, 0.022 inside a galaxy, 0.016 otherwise, and its ring is pushed out to stay round the core (scene3d.js:1526–1530). The core is drawn last, at render order 1003, black over its own glow.
The ring. A torus of radius 1.9 and tube 0.3 (0.18 for a Proto Well) in the mark's scale, flat on the skin about the surface normal, scaled by size/mark and by 2.2 for Well #1 and 1.7 for an Ascendant Well, warm orange (faint for a light well, under a tenth of the heaviest, or one inside a galaxy), pale gold for an Ascendant, near white for Well #1. A stellar well is a small dark point, max(mark/2, 0.011·span), with a faint ring only while it feeds.
The disk. A heavy well, or a galaxy's heart that feeds, has an accretion disk of width min(6·size, 2·size + 5·mark), a 128 × 128 texture of three trailing arms, cos(3a + 9 ln r), falling as (1 − (r − 0.22)/0.78)^1.6 from a bright inner edge at r = 0.26, clear inside r = 0.22 (diskTexture() scene3d.js:974). render() turns each well's second child 0.025 radians a frame (scene3d.js:2147) to spin its disk. The disks of heavy bodies (Part 8.7) turn by their own rate.
Seyferts and quasars. From an Eddington ratio of 0.01 a glow sprite of 0.04 + 0.05·e (a Seyfert); from 0.1 a brighter one of 0.09 + 0.25·e (a quasar) and two jets along the normal, min(0.6, 0.12 + 0.45·e) long and 0.012 wide, e = min(1, ratio) (scene3d.js:1541–1549).
Well #1's hoop (placeAlphaHoop() scene3d.js:1700): a gold ring on the screen round the heaviest well, d = min(max(22, 2·r_px), 48) pixels across, r_px the black core's radius on screen times 1.3, dimmed when the well is on the far side. Ascendant Wells carry a tag "#rank · Ascendant" (syncWellTags(), placeWellTags()); the optional labels give each well's side, its angles u and v in degrees, and its position (placeWellLabels() scene3d.js:1731).
Ripples (addRipple(r, c, k) scene3d.js:1598, stepRipples() scene3d.js:1663). A merger, or the heaviest inspiral of a decay step, with k its shed energy over the matter's total, sends a train of three crests across the skin:
strength = min(1, 0.45 + 6·k)
radius_j = max(0.3, 0.5 + x·rows/2 − j·0.035·rows) for crest j = 0, 1, 2, x = age / 3.6 s
width = (0.5 + 0.8·strength)·rows/256
fade_j = (0.55 + 0.45·strength)·(1 − x)^0.7·(1 − 0.3·j)
each a band of 96 segments, its column offsets scaled by the local cell aspect, at most 4, so it is round on the surface. Ten trains run at once; a new one replaces the oldest.
Moving. Proto Wells and physical wells with a velocity are moved between steps to (r + v_r·frac, c + v_c·frac) (scene3d.js:2144–2146; frac in Part 8.9). moveWells() scene3d.js:1168 moves marks without rebuilding them.
In the game
Wells first appear at the Data Nova as Proto Wells (Part 8.6). From the Physical Nova each physical well that can be seen is a black core in a warm orange ring, flat on the skin; most are small, and a well with a galaxy round it is a third of the size, so the eye reads the galaxy first and the well at its heart, as BPT Part 3.14 asks. A well whose horizon is wider than its mark is drawn as a black disk on the skin at its true size. A heavy well has an accretion disk of three trailing arms round it. A well that feeds above a hundredth of its Eddington rate lights with a glow, a Seyfert; above a tenth it blazes, a quasar, with two jets standing up from the skin along its axis. An Ascendant Well wears a pale gold ring and floats a tag "#rank · Ascendant" (scene3d.js:1554); Well #1 has a near-white ring, larger than the rest, and a gold hoop drawn round it on the screen, dimmed when it is on the far side. When two wells merge, pale cyan rings, three crests in a train, spread out across the skin from the merger and fade.
The "Wells:" readout counts them against the Progeny Count Law: at a deep level … counted · … drawn · law …, … unseen at level L, at the model level … · law …, with · … sites waiting while sites still wait for their wells (app.js:2141–2142); the tooltip says "the law is compared, never imposed" (index.php:85). "Show the wells' rings" (index.php:194) hides the rings, and "Well labels", "In 3D, name each well and say where it really is", labels each drawn well as W<id> · near side · u …°, v …° · (x, y, z) (scene3d.js:1751). The pointer becomes a pointing finger over a well; a tap chooses it (Part 8.10).
The scale model
A drawn horizon is to scale whenever it is larger than its mark (a horizon of h cells is h·cellW across). Otherwise the mark is a picture: 0.006 to 0.031 scene units by mass, about a few pixels at the default view, never to scale. Each drawn well stands for wellMult of the level's wells (Chapter 3); the drawing does not show the multiplier. The ripples' speed is drawn time: half the tube's rows in 3.6 s at every level.
Where the game and the theory differ
- BPT's gravitational waves run at light speed. The drawn crests cross half the tube's rows in 3.6 s of drawn time at every level, and ten trains are shown at once.
render()turns each well's second child to spin its disk (scene3d.js:2147); since the black core was added (2026-10-29) the second child is the core, a sphere, so the well disks no longer visibly turn.- The gold hoop's comment says it is never under 30 px; the code's floor is 22 (
placeAlphaHoop()scene3d.js:1710). - The well's own sphere is set to render order 1003 and then, a line later, to 999 (scene3d.js:1518–1520); the core child keeps 1003.
Fixed numbers
| Number | Where | What it is | Kind |
|---|---|---|---|
| 0.01, 0.1 (Eddington ratio) | scene3d.js:1497, 1541–1544 | feeding, Seyfert, quasar | PHYSICS (Eddington 1926; the thresholds as set in app.js, Chapter 3) |
| 0.35, 0.006, 0.0025, 10 | scene3d.js:1488 | mark size by mass | DISPLAY |
| 2π·(HOLE + TUBE·scale)/cols | scene3d.js:1484 | cell width for a horizon to scale | PHYSICS (exact length on the drawn torus) |
| 0.1 (light well), 0.011 | scene3d.js:1473, 1500 | dim and stellar marks | DISPLAY |
| 0.03, 0.026, 0.022, 0.016, 1.55, 1.08, 1.6 | scene3d.js:1526–1528 | black cores at least a few pixels | DISPLAY |
| 1.9, 0.3, 0.18, 1.8, 8 × 48, 6 × 24, 2.2, 1.7 | wellKit() scene3d.js:950, 1522 |
ring shapes and scales | DISPLAY |
colors and opacities of wellKit() |
scene3d.js:953–965 | horizons, rings, disks, jets, glows | DISPLAY |
| 16 × 12, 8 × 6, 48 | scene3d.js:950–951 | sphere and circle segments | METHOD (tessellation) |
| 6, 2, 5 | scene3d.js:1539 | disk width | DISPLAY |
| 128 px, 0.22, 0.26, 0.05, 0.78, 1.6, 3, 9, 0.55, 0.45, 200, 40, 120 | diskTexture() scene3d.js:976–983 |
the disk's arms and inner edge | DISPLAY |
| 0.025 rad a frame | scene3d.js:2147 | intended disk turn (now turns the core) | DISPLAY |
| 0.04, 0.05, 0.09, 0.25, 0.6, 0.12, 0.45, 0.012, 14 | scene3d.js:1543–1547 | glow and jet sizes | DISPLAY |
| 64 px, 0.25, 0.7 | glowTexture() scene3d.js:971 |
glow sprite | DISPLAY |
| 22, 48, 1.3, 1.1 | placeAlphaHoop() scene3d.js:1707–1710 |
the gold hoop's size and visibility | DISPLAY |
| 1.05, 0.03 | scene3d.js:1724, 1747 | tag visibility margin, far-side tolerance | DISPLAY |
| 10 (RIPPLE_MAX) | addRipple() scene3d.js:1600 |
ripple trains at once | CAP |
| 96, 3 (CRESTS), 4 | scene3d.js:1600, 1611 | segments, crests, aspect clamp | METHOD (96: a round band; 4: no wrapping at the throat) and DISPLAY |
| 0.45, 6 | scene3d.js:1611 | crest strength by energy share | DISPLAY |
| 3.6 s, 0.035, 0.5, 0.8, 256, 0.3, 0.55, 0.45, 0.7, 1.15, (0.5, 0.97, 1.0) | stepRipples() scene3d.js:1665–1671 |
crest timing, gap, width, fade, color | DISPLAY |