Star noise at 5k ticks: the stellar disk stops rotating by t=2500, the gas does not #66
Labels
No labels
burndown-2026-06
autonomy
async-consult
autonomy
epic
autonomy
headless
autonomy
live-collab
c#
priority
P0
priority
P1
priority
P2
priority
P3
priority
P4
role/ai
role/creator
role/design
role/director
role/engineer
role/exec
role/human
role/ops
role/qa
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
coilyco-gaming/galaxy-gen#66
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Measured before tuning anything.
ward exec debug-sim 5000 500 3 12345 2— irregular=>spiral, size 500, seeds 12345/12346/12347, checkpoints to 5000.The finding
svt(stellar mean tangential velocity) collapses to zero and stays there. Gasvtdoes not.All three seeds, same shape: stellar rotation decays from ~+1.6 to ~0 between t=900 and t=2500, then stays at zero. A stellar population with mean tangential velocity of zero is not a disk. It is a pressure-supported random-motion cloud, and with 31k-52k resolved stars drawn on top of everything else, it is the dominant visual layer. That is the uniform mess.
The gas is fine. Gas
vtholds +1.05 to +1.34 at t=5000, and gas spiral coherence at 5000 is 0.53 / 0.31 / 0.34 across the three seeds - as good as or better than at t=1000. The structure is still there. It is being buried under a non-rotating star field.This reframes the problem: it is not "too many stars" and not "structure decays." It is one population losing its rotational support while the other keeps it.
Mechanism
Two asymmetries between how gas and stars are integrated, both in the same direction.
1. Gas has a dissipative relaxation term. Stars have nothing equivalent. Gas velocities decay toward the circular flow every tick via
flow_drag(flow_decayat galaxy.rs:4001, per-scenario 0.015-0.035). That is an active energy sink continuously re-aiming gas onto circular orbits, which is why gas stays coherent indefinitely. Stars are collisionless by design and only getSTAR_HALO_DRAG, and only while out in the halo band. Inside the disk nothing removes their velocity error, so any error integrates and the population randomizes.2. Stars inherit gas velocities but read a much weaker field. The coarse field is built with
v_flat_star = p.v_flat * 0.5and then everything multiplied bySTAR_FIELD_SCALE = 0.25(galaxy.rs:2075-2101). So a star feels roughly a quarter of the centripetal support the gas feels - but it is born carrying its natal gas parcel's velocity, which is calibrated to the full gas rotation curve. Born too fast for its own potential, it climbs onto a large radial excursion, and the population phase-mixes within a few orbital times. The observed t=900 to t=2500 decay is about the right timescale for that.The halved pace is deliberate ("so star orbits run at half the gas pace"), and that is fine as art direction. The problem is that the birth velocity was not halved to match it.
This is not a new discovery so much as an unfinished one.
BIRTH_GAS_VEL_CAPalready exists, and its comment says inheriting the raw gas velocity "launches newborns straight into the halo and empties the visible disk." Same failure mode, met once before and capped rather than resolved. The cap bounds the worst case; it does not make the inherited velocity consistent with the potential the star will actually feel.Why this is probably also #65
#65 records a 2x stellar luminance bump pooling just outside
disk_rat maturity. Stars born with too much energy for their potential are exactly the stars that climb out of the disk and pool in the halo band. One mechanism, two symptoms. Worth fixing once rather than twice.Proposal
In order, measuring
svtat t=2000/5000 after each step rather than stacking changes:svtholds above ~1.0 at t=5000, everything below is unnecessary.flow_drag, applied only insidedisk_r, enough to bleed accumulated error without making the population collisional. This trades some physical purity for the thing the sim is actually for, which is looking like a galaxy.FIELD_RES = 64. At size 500 each field cell spans ~7.8 sim cells, so stars cannot resolve arm structure at all. This limits how much spiral detail the stellar layer can ever show, but it is not what is killing rotation, so it should not be touched until 1 and 2 are settled.Do not start by cutting the birth rate. The star count is a symptom of nothing - 50k rotating stars would look like a galaxy.
Measured it. The hypothesis was right in direction and badly understated in magnitude, and the mechanism is not the one I guessed.
Added two probes to
debug-sim:scirc— mean disk-star tangential speed over the circular speed of the field those stars read. 1.0 is a balanced disk.bcirc— the same ratio a newborn is handed at 0.5disk_r. Separates "born wrong" from "drifted wrong".irregular=>spiral, size 500, seeds 12345 / 12346:
bcircsits at 2.0-3.2 for the entire run. Newborn stars are handed two to three times the circular speed of the potential they have to orbit in. Past about 1.41x circular a star is above escape velocity for its own potential, so the disk has been launching the large majority of the stars it forms, continuously, from t=250 onward.scircthen tells the rest of the story: the surviving disk population starts at 1.3x circular (already too fast) and decays to 0.28x by t=2500. The fast tail leaves. What stays is the low-angular-momentum remainder, which is sub-circular and falls inward. Neither group is on a disk orbit, so there is no rotating disk left — just a pressure-supported cloud of 40k points drawn over the still-perfectly-good gas structure.Cause
Not the field scaling, and not the missing relaxation term. Both of those are fine. It is this line:
ASSOCIATION_ORBIT_SPEED_CAP = 2.1is an absolute speed, and it binds on essentially every birth. Circular speed in the star field at 0.5disk_ris around 0.8, so a 2.1 ceiling is ~2.6x circular. A single absolute number cannot be right across radii and scenarios where circular speed varies by a factor of several — it is far too generous in the disk and would be too tight elsewhere.The compensation stack above it is also additive:
gas_tangential + 1.08 * v_circ + background_support. Sinceassociation_circular_speedalready returns the true circular speed of the quarter-strength field stars actually read, adding a background halo/BH term on top double-counts the support. But the cap is what makes it extreme.Fix
Clamp to a multiple of the local circular speed instead of to an absolute speed:
1.06 keeps newborns just above circular — enough eccentricity that the disk looks alive rather than on rails, and far below the ~1.41 escape ratio. The absolute cap stays as a backstop for degenerate radii where the sampled field is unreliable.
Re-measuring now. This also predicts #65 goes away, see there.
Built the ratio cap, measured it, and reverted it. It works exactly as designed and it is still not landable. Two findings, one of them the important one.
The fix does what it claims
BIRTH_ORBIT_RATIO_CAP = 1.06, irregular=>spiral, seeds 12345 / 12346:bcirc(birth ratio)mixed@ t=2500Stars draining into the halo reservoir dropped by roughly 70x. That confirms the #65 mechanism outright: stars were being launched past escape, piling at the phase-mixing radius, and retiring. Stop launching them and the drain nearly stops.
But rotation still decays, so #66 has a second cause
scircfrom a now-correct start:Born at exactly circular, the population still loses its rotational support within ~1000 ticks. So birth velocity was a real bug, but it is not what is killing the disk. Something is actively heating stars that are already sitting correctly.
Leading candidate is now numerical rather than physical:
FIELD_RES = 64against a 500-cell grid means each field cell spans ~7.8 sim cells, and stars integrate by sampling that coarse, clump-dominated field. Discrete-field scattering converts ordered rotation into random motion on about this timescale. This was item 3 on the original list and the data promotes it to item 1.The important finding: the elliptical scenario is built on this bug
ward exec test-rustwith the cap applied, 4 failures:The elliptical goes to 0.95 stellar concentration — nearly every star inside 0.3
disk_r. Its "relaxation into a pressure-supported spheroid" is currently being produced by the over-fast births: stars launched at 2-3x circular are what populate the spheroid out to large radii. Give them correct orbits and they stay where they were born, which in that scenario is the middle.So this is the same shape as the gas confinement ridge in #65: a bug that a scenario's visual identity depends on. Two for two. Fixing the birth velocity is not a constant change, it is a redesign of how the elliptical builds its spheroid — most likely giving it explicit velocity dispersion at birth, which is what a real pressure-supported system has, instead of borrowing the side effect of a bad cap.
Landed instead
Only the diagnostics, which are inert and pass all 83 tests:
Galaxy::star_circular_ratio()andGalaxy::birth_circular_ratio(frac)scirc/bcirccolumns indebug-simSuggested order now
FIELD_RESfirst). If stars will not hold a disk orbit even when born on one, the birth fix cannot be evaluated properly anyway.Correction to my previous comment. The intervention test does not support the causal story I gave, and one of my two probes is not measuring what I said it measures. Retracting both claims before anyone builds on them.
Full intervention matrix,
scircat t=2500, seeds 12345 / 12346FIELD_RES = 192onlyThe birth cap makes the metric worse or flat, in both field resolutions. It does not restore stellar rotation. My claim that over-fast births cause the rotation collapse is not supported — capping births to circular does not fix it, and combining the two fixes is no better than doing nothing.
FIELD_RES = 192alone is the only configuration that improves anything, roughly doubling retained rotational support, at 9x the field-build cost.Why the earlier conclusion was wrong
Two separate errors.
1.
bcircstopped tracking behaviour. When I reverted the cap I reverted it in the probe too, but then re-applied it at the birth site for the combined run. Sobcircin that last sweep reports the uncapped target ratio (1.76-2.84) while births were actually capped. The probe and the code disagreed and I read the probe. That is my bug, not the sim's.2.
scircprobably does not measure what I claimed. It is mean tangential speed over local circular speed across disk stars. That does not distinguish a star on a circular disk orbit from a star on an eccentric orbit passing through pericenter, where tangential speed is high by construction. So a population of fast eccentric interlopers scores well. That plausibly explains the whole inverted result: uncapped births produce eccentric orbits that inflatescircwhile looking exactly like the mush being complained about.If that reading is right,
scircis close to useless for this question and the t=250-to-2500 decay I built the whole diagnosis on may be measuring a change in orbit eccentricity rather than loss of rotation.What still stands
Only the arithmetic, which is not inference:
ASSOCIATION_ORBIT_SPEED_CAPis an absolute speed of 2.1 that binds on nearly every birth, against a local circular speed near 0.8 at 0.5disk_r. Newborns really are handed 2-3x circular. That remains a defensible thing to call wrong on its own terms. What is now unsupported is that it causes the visual mush.The elliptical finding also stands and is independent of all this: capping births to circular collapses that scenario to 0.95 stellar concentration, so its spheroid does depend on the current birth speeds.
What the next person should do
Do not tune anything against
scircuntil it is replaced. It needs a metric that separates ordered rotation from random motion properly — the standard one isv_rot / sigma, mean streaming velocity over velocity dispersion in radial bins. Dispersion is the thing that actually distinguishes a disk from a mush, and it is exactly what I failed to measure.Concretely:
v_rot / sigmain radial bins. Confirm on a case with a known answer, e.g. the elliptical should score low and a fresh spiral high.FIELD_RESresult is the one most likely to survive, since it improved a metric that was biased against it.Working tree is reverted;
maincarries only the inert probes at916cf8e. Leavingscircandbcircin place for now, but the doc comments on both need the caveat above before anyone trusts them.Rebuilt the measurement and re-ran everything. The phenomenon is confirmed and neither candidate fix resolves it.
The metric now has a known-answer test
Galaxy::rotation_dispersion_ratio()—v_rot / sigmain radial bins, landed in6c180eb. Calibration test: 400 stars on cold circular orbits must read above 1.5; the same positions and speeds with velocity directions scrambled must read below 0.7; the two must differ by 3x.That test caught a bug in the metric on its first run. A perfectly cold disk returned 0 — zero dispersion tripped the small-sigma guard, so every bin was discarded as "no data" and maximal rotational support scored as none. Fixed by flooring sigma rather than dropping the bin. Without the test it would have produced another believable curve.
Confirmed: this is a real disk-to-spheroid transition
vsig, irregular=>spiral, baseline:Starts firmly rotation-dominated (>1.5), ends firmly dispersion-dominated (<0.7), crossing over around t=1500. Not a rendering artifact, not a star-count problem, not a metric artifact. The stellar disk is being heated into a spheroid.
FIELD_RES = 192survives the better metric but does not fix itLate-time
vsigimproves ~1.6-1.8x, consistently across seeds. Early and mid times are neutral or slightly worse. So field coarseness is a real contributor to the late-time heating — my earlier prediction held up — but the disk still crosses into spheroid territory at the same time and still ends well below 0.7. It is not the cause. At 9x the field-build cost for a partial late-time effect, it is not worth landing on its own.Confound worth noting: RES 192 also nearly doubles the star count (83802 vs 43656 at t=2500), so some of the
vsigdifference may be improved statistics rather than improved dynamics.Where this leaves the two candidates
Neither is the answer. The disk is being heated by something else, strongly enough to convert
vsig3.0 to 0.4 within ~2000 ticks.Next diagnostic: ablation, not tuning
Do not tune another constant. Find the heat source by turning candidates off one at a time and watching whether the
vsigcrossover moves:STAR_FIELD_SCALE), so the spiral and ring structures they scatter off sweep past at roughly twice their orbital rate. That is a recipe for resonant heating and it is a design consequence, not a bug. Test by matching star orbital pace to the gas for one run.ShockWaveand the association internal potential both perturb nearby stars. Test by disabling each.Whichever one moves the t=1500 crossover is the cause. Item 2 is my first guess, because the half-pace design puts the whole stellar population permanently off-resonance with the structures it lives in.
Working tree reverted to
main; only the metric is landed.Ran the ablation matrix. Found it. There are two heat sources, not one, and each is on its own sufficient to destroy the disk - which is exactly why one-at-a-time ablation came back empty.
First, the harness
Switches now live in the kernel (
src/rust/ablation.rs), read from the environment, all off by default.debug-simprints the resolved configuration as its first line. This is a direct response to the retraction above: a switch the sim itself reads cannot drift from what ran.Galaxy::birth_circular_ratioreads the same switch as the birth site for the same reason.Baseline reproduces the published numbers exactly -
vsig2.48 / 3.71 / 1.62 / 1.13 / 0.57 / 0.48 for 12345 and 2.76 / 3.14 / 1.59 / 0.70 / 0.38 / 0.31 for 12346 - so the harness is measuring the same galaxy.Worth recording that only two force paths reach a star at all: the coarse field, and the association binding potential.
STAR_WAVE_COUPLINGis 0.0 and supernovae kick gas, not stars. So the candidate list was closed, not open.Single-factor sweep: everything is negative
vsigat t=2500, irregular=>spiral, size 500, seeds 12345 / 12346:Not one of them prevents the crossover. Field staleness, clump scattering, non-axisymmetric structure, stars scattering off each other, the binding potential, and birth dispersion are all individually innocent.
The age split, which is what made the rest legible
Pooled
vsigcannot tell post-birth heating from generations piling up on different birth orbits. Addedrotation_dispersion_ratio_for_age, with a calibration test pinning the discrimination on both cases. It also pins the magnitude, which turned out to matter: two perfectly cold cohorts a factor of two apart in streaming speed still pool to 4.2, so generational offset alone cannot drive pooledvsigunder 1.0. I had guessed otherwise and the test corrected me before it reached this thread.Baseline cohorts, seed 12345:
The young cohort stays a disk for the entire run, at every checkpoint, in both seeds. Star formation is producing perfectly good disk stars at t=2500 just as it was at t=250. Stars are heated after birth, from ~2.5 to ~0.3 within about 500 sim-time units of age, and the pooled decline is the growing old fraction. Nothing is wrong with the disk's ability to make a disk.
Both factors together
The birth ratio cap was built and reverted before
rotation_dispersion_ratioexisted, and judged againststar_circular_ratio, which the retraction above disqualified. So its effect on the disk had never actually been measured. Measuring it, together with the field ablations:vsigat t=2500:Old cohort, the population that was reading 0.28 / 0.24:
There is no crossover. The disk is rotation-dominated at t=2500 and the old stars are rotation-dominated, which has not been true at any point in this investigation. With the probe now mirroring the site,
bcircreads 1.06 exactly, andvsigholds 4.5-5.3 through t=1500 at size 500.Why neither works alone
Two independent mechanisms, each sufficient:
Fix one and the other still finishes the job on the same schedule. That is the shape single-variable ablation is structurally blind to, and it is worth writing down for the next sweep that comes back empty.
Cost, measured
This is not landable as it stands, and it fails in the direction already predicted on this issue.
disk_rgoes 0.03-0.14 to 0.16-0.17 for irregular=>spiral at size 500. At the size-150 test scale the four scenarios at t=1200 go: ellipticalecon0.76 -> 0.93 andsctr0.66 -> 0.86; bang=>spiral coherence 0.36 -> 0.11; irregular=>spiralsctr0.07 -> 0.45. The ring survives intact (ring0.97 -> 0.98,hollow0.99 -> 0.99). Treat the size-150 pass as indicative only.vsiggoes 0.51 -> 3.16. A pressure-supported spheroid that is rotation-dominated is the wrong object. Same finding as before, now with a metric that can see it.arm1.56 / 1.07 against baseline 1.02 / 1.12, since stars are born in the arms regardless), but the honest reading is that we now know what the stars need - a smooth potential for orbital support - not yet how to give them that and the arms too.STAR_WAVE_COUPLINGexists for exactly this and is currently 0.0, which makes it the obvious first thing to try.Suggested order now
STAR_WAVE_COUPLINGabove zero for arm tracing, birth ratio cap for correct initial orbits. A coherent wave should not heat the way a clump-dominated 64-grid field does. Cheapest path from a diagnosis to a design.Landed on
main: the harness, the age-resolved metric, calibration tests for both field filters and for the age split,ward exec ablation-sweep, and docs/ablation.md. Every switch is off by default, the wasm build reads no environment, and the golden mass field test is untouched and green - 91 tests pass. No physics has changed onmain.Stopping here rather than starting the scenario redesign: it is a deliberate multi-scenario retune with golden fields regenerated, and pushing to
mainrolls the public site.Compiled into #70, which owns the fix from here.
This issue and #65 turned out to be one root cause: stars are put on orbits the potential they read cannot hold, and two independently sufficient mechanisms convert that mismatch into random motion. #70 carries the evidence, the three-part change, the measured cost, and the ordered work items.
Nothing open here is left behind - every question on this thread is a work item there. Keeping this open for its history and for the measurement record until #70 lands.
Closing as superseded by #70, on that issue's own accounting:
The three-step proposal here was overtaken by the ablation evidence #70 compiled. Step 1 - scale birth velocity to the field stars actually read - is #70's item 1, now expressed as a ratio cap against local circular speed rather than an absolute one. Step 2, weak orbital relaxation for disk stars, was tested and is not needed: every single-factor ablation is negative, and the disk holds only when the birth-orbit cap and a smooth field are applied together (
vsig0.48/0.31 baseline against 2.25/2.44 for both). Step 3,FIELD_RES, is subsumed by #70's item 2, designing the shipping smooth field.The diagnosis here stands and is worth keeping visible: the heating is entirely post-birth, the star formation was never the problem, and the gas was always fine. #70's age-resolved measurement confirmed it - the young cohort reads 2.91 / 2.22 / 2.44 / 2.12 at t=900 through 2500, so the sim makes good disk stars at maturity exactly as it does at t=250.
No leftovers. #70 owns the change.