Chapter 3 · Section 10
Wells That Meet: mergeWells()
The BPT law
BPT Part 2.8 (Pulse Diameter Variability and Merger-Origin Dynamics) holds that "not all Null Wells are seeded equally — the conditions of their formation define the temporal structure of the universes they generate." Its Null Well Collision Channel Classification sorts the channels, from direct gas-cloud collapse (C(⇌) 0.98 – 1.00, "minimal compression") to Kerr–Kerr mergers, and the UniSpheral Origin Compression Factor ⟪C⟫ = ⟪F⟫(M₁, M₂, a₁, a₂, θ) reads a child's clock from its parent merger; Part 6.8 gives its formal structure. BPT Part 3.13 gives a merger's cost to the space layer, the Gravitational-Wave Power, P_GW = (32/5) · G⁴ · m₁² · m₂² · (m₁ + m₂) / (c⁵ · a⁵), "the power two orbiting masses give the space layer": "Gravitational waves are the working of the space layer." BPT Part 3.14 (Reading a Lineage) asks for each merger's signature, and its reading of the game says: "A merger that carries any well past an eighth of its universe is announced as an Ascendant Well, and its tag floats with it from then on" (ruling at app.js:1712, 2026-10-29: "that ascendent well is most likely caused by wels merger").
The established physics
- The energy two non-spinning wells radiate as they merge follows the numerical-relativity fit of Barausse, Morozova & Rezzolla 2012, as
gwFraction()matter.js:70 names it: E/(m₁ + m₂) = 0.0559745η + 0.580951η² − 0.960663η³ + 3.35241η⁴, with η = m₁m₂/(m₁ + m₂)². That is 4.8 % for equal masses. - The pull is softened inside ε = (10GM)^(1/3), the computation's own resolution, "the softening every N-body code uses, not a law" (
Matter.reach()matter.js:320–324).
The game's math
mergeWells() app.js:1667, once a step after the matter moves:
- Search span. With m₁ and m₂ the two heaviest masses, SPAN = max(2, 2G(m₁ + m₂)/𝒞→², ∛(10Gm₁) + ∛(10Gm₂)). Wells are hashed in cells of that size, and only neighbor cells are tried (2026-10-28; profiled: 6 % of a physical step tried all ~370 × 370 pairs).
- Merge test for a pair at wrapped distance d. They merge if their horizons touch, d < max(2, 2G(m_a + m_b)/𝒞→²). They also merge if they are bound, |Δv|² < 2G(m_a + m_b)/max(1, d), and within reach, d < ∛(10Gm_a) + ∛(10Gm_b). Inside that reach their last orbits are faster than a flip can follow.
- Sites. If either is a site,
siteMeets()handles it (Part 3.7). No black-hole merger happens. - The merged well. It sits at the mass-weighted center and keeps momentum. Its spin is set as in Part 3.9. Its mass is M − E with E = gwFraction(m_a, m_b)·M radiated to the space layer (
radiate('gw')). Two hearts' own Suns add, less the same share. A heart stays a heart. - Ascendant by merger. The merged well's share, sh = mass / max(matterMax, matterTotal) (÷ starMult for a stellar well). If 8.1·sh ≥ 1, the well is marked Ascendant on the spot and announced.
- Signature. m₁, m₂, q, a₁, a₂, θ, both shares and ranks, the energy shed, the spin out, the child's a_f and axis, and the point in the life are pushed to
mergersand to the well's record. - One merger a step. The function returns after the first merger ("the list has changed").
In the game
The player sees a merger as two black spheres becoming one and a gravitational wave leaving the spot: a train of three bright cyan bands, the strongest first, running out across the skin from the merger and fading as it spreads, crossing half the tube in 3.6 seconds, brighter the larger the share of the universe shed (addRipple() and stepRipples() scene3d.js:1598–1684; up to ten at once). A merger that carries a well past an eighth of its universe rings out twice, a second wave 400 ms after the first, and the well gains a floating tag, "#3 · Ascendant", from that moment (app.js:1715; scene3d.js:1554). Its notice reads "Two wells met and the one they made holds 14.2% of the universe, past an eighth: its child will stand at this universe's level or higher (book Part 3.14, Ascendant Wells)", held while notices are quiet. Each merger goes on both wells' life lines ("merged with Well #9 at Tempo 480", "fell into Well #2 at Tempo 512"), and the dive card for a merged well says "merged with …" (app.js:3128). The run summary's finds row counts "↻ N mergers".
The scale model
Masses are drawn masses. A merger of two drawn wells stands for the merger of the wells they represent. The share test divides a stellar well by starMult, as the census does (Part 3.14).
Where the game and the theory differ
- The Barausse, Morozova & Rezzolla 2012 fit used by
gwFraction()is the fit for non-spinning wells. The game's wells spin (Part 3.9), and the fit is applied to them unchanged, with no term for a₁, a₂ or their alignment.
Fixed numbers
| Number | Where | What it is | Kind |
|---|---|---|---|
| 2 | app.js:1675, 1688 | least merge distance, two cells | CAP (a floor on reach; the grid's resolution) |
| 2 (in 2GM/c²) | app.js:1675, 1688 | horizon radius | PHYSICS (Schwarzschild) |
| 10 | app.js:1675, 1686; matter.js:324 | ε = (10GM)^(1/3) | METHOD (softening at a tenth-of-distance bend per flip, stated) |
| 1e-9 | app.js:1675 | span guard | METHOD |
| 0.0559745, 0.580951, 0.960663, 3.35241 | gwFraction() matter.js:73 |
radiated fraction fit | PHYSICS (Barausse, Morozova & Rezzolla 2012) |
| 1 merger | app.js:1724 | one merger a step | CAP (limits mergers per step; could merge every touching pair) |
| 8.1 | app.js:1715 | Ascendant share line | BPT (Ascendant Mass, Part 3.14) |
| 0.2, 0.12, 400 ms | app.js:1715 | ripple size and delay of the announcement | DISPLAY |
| 4, 6 | app.js:1717–1719 | rounding of the signature | RECORD |
| 450, 180 | app.js:1702 | axis angle folded to [0°, 180°) | METHOD (an axis has no sign) |
Measured
- "profiled: 6 % of a physical step tried all ~370 × 370 pairs every sub-step" (comment app.js:1670, 2026-10-28).