diff --git a/docs/aetheria-gravity-map.md b/docs/aetheria-gravity-map.md index 16995ed5f..33f220aa3 100644 --- a/docs/aetheria-gravity-map.md +++ b/docs/aetheria-gravity-map.md @@ -77,6 +77,10 @@ All read at c6519383 in the detached worktree `C:\aeth-wt\ag2-docs` on 2026-10-1 - **B37. Bodyless parents and the ring law.** ZoneGenerator's `ExpandRosette` (ZoneGenerator.cs:551-592) leaves the parent node empty and puts n children on one circle at phases i/n; binaries are rosettes of two (:484-487), roots can be rosettes of suns (the probe's 321 empty root suns), and a later `ExpandSolar` on an empty node adds outer children beyond the ring. In 2D a point of strength c_j at distance s on the same circle pulls a ring member inward by exactly c_j/(2d) (radial part of c_j/s with s² = 2d²(1-cos θ)), so a ring member's rail is v² = ½·Σ_{j≠i} c_j; and by 2D Gauss's law, which holds for log potentials, a ring exerts c_ring/d on anything outside it and nothing on anything inside it. So the field gives every child of an empty node a definite pull: the strength of its siblings strictly inside its distance, each with its whole family (a sibling's moons orbit with it), plus half the strength of siblings on its own circle (within 0.1 u, the generator's own rosette test, ZoneGenerator.cs:227) when the child itself carries strength. The last clause keeps a bodyless companion (a station or turret orbit at a planet's distance) on its planet's period: neither the planet nor its companion counts the other. Probed: no child of a generated zone is left without a field under this rule (B35), and nested binaries (an empty binary member that holds its own binary) get the ring term through their family's strength. - **B38. Parent-only rails against the summed field** (`o1.py`). By 2D Gauss's law (B37) the phase-averaged pull at a child's distance from a body parent is the parent plus every sibling inside that distance, each with its family; siblings outside pull nothing on average. The circular speed of that enclosed field over the parent-only rail speed (B35), p10/p50/p90/p99, by the child's class: suns (children of a root or rosette) 1.44/1.98/2.44/2.75, gas giants 1.00/1.58/2.14/2.55, planets 1.00/1.21/1.65/2.05, planetoids 1.00/1.00/1.37/1.61, belts 1.00/1.14/1.49/1.88. Enclosed speeds: suns' children 24.4/46.0/60.3 u/s, planets 11.0/21.8/32.3. So under the funnel the operator kept (`funnel-kept-until-flown`), a ship coasting free at a body's orbital radius, away from the body, needs 1.2-2x the body's rail speed; patched conics' premise, that the parent dominates, is weak where c ∝ m^0.2 (the root holds 18% of a zone's total c, B19). The enclosed rule would also break field-strength-ruled's 12-18 u/s for planets round a median sun. Question `aetheria-gravity:question:rails-enclosed-or-parent` carries the fork; the two options differ by one term in one function. - **B39. Planets are drawn at the step, the camera at the drawn time** (source read and Yggdrasil probe at 09ec04a8, 2026-10-15, after the operator's flight: "if I look at the planet while doing that, it jumps back and forth every frame"). `ZoneRenderer.Update` places each planet at `Zone.GetOrbitPosition` (ZoneRenderer.cs:582-585), the cached `Orbit.Position` the last `Zone.Update` wrote (Zone.cs:507-532), with no `Lead`; ships, and through them the follow camera, are drawn `Lead` past that step (EntityInstance.cs:405, B32). The sim runs before every presenter in the frame (ActionGameManager executionOrder -10, ZoneRenderer 50), so the gap is one of clocks, not of order. Probe (`DrawnPoseProbe.cs`, Imagination scratchpad `imagination-ag3-planet-jitter/`, via ygg-verify): a ship kept 60 u beside a planet moving 20 u/s, sim at 60 steps/s; planet-minus-ship along the motion spans 0.306 u at 144 Hz with 239 reversals in 286 frames (75 Hz 0.27, 120 Hz 0.17 reversing every frame, 165 Hz 0.30, 240 Hz 0.25, 60 Hz 0). Amplitude is the planet's speed x Step, so orbits-from-field (B35) made it 2.65x larger. Evaluating the orbit at `ExactTime + Lead` gives 0.0002 u and no reversals. Also drawn at step time: belts and the belt UI (`EvaluateBelt` at `_time`, ZoneRenderer.cs:546-549, 719), the drawn wells (GravityLowering.cs:53), loot and mines (`Body.Position`, ItemPickup.cs:43-44, MineInstance.cs:58-59), the chunk reticle (ActionGameManager.cs:1184) and the flow clock (VolumeSampling.cs:112); the ship's drawn ride height reads wells at step positions (source-read consequence, unprobed). Stations, clouds and rounds are already drawn ahead. `LookAtPoint` and group aims read the previous frame's drawn transform (EntityInstance.cs:396 before 405-406). Fixed by `cut-drawn-pose-at-drawn-time.r1`. +- **B40. The conserving compact law** (`docs/research/gravity-well-law.md` section 1, b2f6122d; Imagination 2026-10-15). Building block: a band term U(eps, a, b) with pull r/(r^2+eps^2)*B(r^2), B = 1 inside a, fading to 0 by b with S(t) = 35t^4-84t^5+70t^6-20t^7, 0 beyond; closed-form potential (one log plus a polynomial), so the drawn grid is exactly the potential. Each orbit-tree node F contributes c(m_F)*U(eps_m, L_F, B_F) + c(M_F)*[U(eps_M, max(B_F, Lambda_F/2), Lambda_F) - U(eps_M, L_F, B_F)], with m_F the body's mass, M_F the family's, c and eps the existing WellStrength and Roche curves, L_F the outermost child's distance, B_F the family's support, Lambda_F = max(2*d_Hill, 1.5*B_F) its reach; the root has no reach; a bodyless node's ring group stands in for its body. Inside L_F the node pulls exactly as its body; beyond B_F exactly as one body of mass M_F; beyond Lambda_F not at all. Checks: F = dphi/dr to 1.6e-9; derivative jumps of order 0-4 are zero at 50 digits at band edges (C4), C-infinity elsewhere; Plummer core (no C1 seam); 0 containment violations in 70,890 term/ancestor pairs; float32 height error about 2e-3 u. The family's centre is its body, not its centre of mass (exact merge-in-slot, nothing a test sees is lost). Plummer's peak pull is 0.5*c/eps against the harmonic core's 1.0*c/R, so K halves to 2.049 to keep core-at-roche-and-exaggeration-up's peak drawn slope; slopes outside the cores draw 2x steeper while the tamed funnel pulls about 2.6x less. +- **B41. Probe under the conserving compact law** (`gravity-well-law/probe3-output.txt`, 6 draws, same data as B35/B38). Reach 2*d_Hill (w3): ratio p50 Sun/GasGiant/Planet/Planetoid/Belt 1.09/1.00/0.97/0.97/0.98 (p90 1.15-1.32) against today 2.00/1.63/1.24/1.10/1.16; far field exactly 1.00x c(M_zone) at 2Z and 10Z (today 5.54x); deepest point 1.01x one body of the zone's mass (today 3.43x, p90 4.83); split invariance outside the family for 2382/2427 families inside the ruled generator window (4573/6976 under today's generator, which places most moons outside it, B25); mid-zone pull 0.60 at Z 1000; planets round a median sun 17.2 u/s, 99% in 12-18; suns' children keep 23.6 u/s rails. 234 children get under half the log pull: the same 234 inside their parent's Roche limit. +- **B42. Evaluation cost of the tree walk.** 30 terms per zone; a sim sample evaluates 4 terms p50 (p99 15) after 10 reach tests; a shader texel 3 (p99 14); today every sample evaluates all 17 wells p50 (p99 58). Skipping is exact because nothing outside a reach pulls; camera-window culling is optional. +- **B43. Consequences the well-law cut carries or names.** The ring law becomes partners' own terms at their chord (a binary member feels c(M_partner)*2D/(4D^2+eps^2)); a body orbiting a binary from outside feels c(M_pair), not the sum of strengths; strengthless companions on a ring keep the mean-pull rule until children-within-reach deletes it; children-within-reach reads the law's reach and support instead of respelling the tidal radius, and places circumbinary children beyond 5x the ring radius. Knobs (smoothstep order, band 1.5, fade from half the reach, ring reach 4D) were chosen once, not swept. ## Model page @@ -123,7 +127,7 @@ Cells not filled, plainly: whether a per-body multiplier on c or the core is eve Mapped and admitted (2026-10-14, base 11b2d7ad): `aetheria-gravity:cut_spec:cut-gravity-subtract.r2` and its sibling `aetheria-gravity:cut_spec:cut-orbits-placed-at-build.r1`, both merged at 5dd1f6b7. Mapped and admitted (2026-10-14, base 5dd1f6b7): `aetheria-gravity:cut_spec:cut-potential-owner.r3` (rebased on 3f5cef68 on 2026-10-15, after rulings `funnel-kept-until-flown` and `core-inside-roche-curve`), one Hands pass; it carries follow-ups `deep-orbit-placement-test` and `gravity-subtract-test-residuals`. Between it and grid-lowering the drawn grid lags (B23). The operator will fly the funnel before ruling on it again (`funnel-kept-until-flown`), so potential-owner and grid-lowering must both be on one playable branch before that flight; grid-lowering is stacked on potential-owner, not a sibling (B26), and its map is the next Imagination pass once potential-owner's report lands. Mapped and admitted (2026-10-15, base dd06f39d, stacked on potential-owner's head): `aetheria-gravity:cut_spec:cut-grid-lowering.r1`, one Hands pass, Starfire-verified; on its branch the drawn grid is the field (B30) and the Sector Waves noise is off the grid until grid-noise-presentation. Mapped and admitted (2026-10-15, base 8f491fd3, stacked on grid-lowering's head): `aetheria-gravity:cut_spec:cut-fog-precision-and-jitter.r1`, the slope jitter (B32) and the patch's second gravity lowering (B33), one Hands pass. Mapped and admitted (2026-10-15, base 8f491fd3, a sibling of fog-precision-and-jitter on grid-lowering's head, disjoint files): `aetheria-gravity:cut_spec:cut-orbits-from-field.r1`, periods from the field (B35-B38), one Hands pass; it raises `aetheria-gravity:question:rails-enclosed-or-parent` and is written for the recommended parent-only option. Not yet mapped: - **drawn-pose-at-drawn-time** (mapped and admitted 2026-10-15, base 09ec04a8: `aetheria-gravity:cut_spec:cut-drawn-pose-at-drawn-time.r1`, one Hands pass): `DrawAhead` owns every drawn pose at T = ExactTime + Lead (B39); closes item 3 of `fog-jitter-residuals`. -- **tail-taming** (ruling `tame-tails-parent-only-rails`): the wells' tails are tamed so the parent dominates near its children and parent-only rails are honest; mechanism waits on the Eyes pass `docs/research/gravity-tail-taming.md`, then Imagination. +- **tail-taming** (ruling `tame-tails-parent-only-rails`): mapped and admitted 2026-10-15, base 8bc5ef18: `aetheria-gravity:cut_spec:cut-well-law.r1` (the conserving compact law, B40-B43), depends on drawn-pose-at-drawn-time; waits on question `tail-taming-law-r2`. - **potential-owner** (mapped, above): one ServerShared potential (c from an authored compressed curve G·m^p, authored core-radius curve, uniform-disc core, log tail, superposition, analytic gradient, no gate, global K in PlanetSettings, reference zero at the root's zone radius); every CPU force reader (Ship, floating bodies, clouds, mines) and `Zone.Flow`'s slope term read it; GetHeight = φ/K; deletes `GravityAcceleration`, `GravityReferenceRate`, `GetNormal` as a force source, the PowerPulse well and `GravityDepthExponent`; field strength per field-strength-ruled. Waits on both admitted cuts. May split into the potential and its readers if one Hands pass cannot hold both. - **children-within-reach**: ZoneGenerator places children inside a fraction of the parent's tidal radius and the core radius inside the innermost child (softening-radius-ruled); tested over generated zones. It reads `Planet.RocheLimit` (lower bound) and half the tidal radius (upper bound); the windows per class are in B25, and a body with no window (4-7% of small bodies) gets no children. Seam: it places children on GeneratorPlanets before any Zone exists, so it needs the strength a child's rail obeys (`Zone.PeriodAround`'s pull: parent well, or the ring law for bodyless parents) over generator data; it lifts that pull to a pure function both read, rather than spelling the ring law a second time, and its tidal radius uses the same pull. Waits on orbits-from-field. - **grid-noise-presentation**: the Sector Waves noise (after grid-lowering on layer 10, drawn only into the nebula patch height) and fine-grid detail move to non-slope presentation (grid-gravity-only-ruled); it also owns the Main Menu's own Surface Displacement brushes (B29, follow-up `menu-grid-brushes`). Waits on grid-lowering.