Chapter 8 · Section 7
Matter as Stars
The BPT law
BPT Part 2.9 (Gas, Stars, and the Stellar Road to the Null Well) opens with where matter comes from: "The physical, in this book, is the data seen at the Tempo (Part 3.6): at the Physical Nova ... the physical layer condenses from the data that has filled the lattice since the Data Nova, where that data lies." Gas collapses into stars past its Jeans mass, the Star Formation Condition M_J = (π²·√π/6)·σ³/(G·√(G·ρ)); stars are born by the Initial Mass Function, dN/dM = ξ₀·(M/M☉)^(−α), "a few heavy ones, a great many light ones"; they live τ⊛ = τ☉·(M/M☉)^(−2.5) on the main sequence, swell in their Giant Phase, and end as white dwarfs, neutron stars that blink as pulsars by Pulsar Spin, or Stellar Null Wells, with supernovae and planetary nebulae as their shells.
BPT Part 2.10 (The Strong Force and the Mass of Matter) counts them. Stars of a Universe (G), N★ = 925·(m_P/m_p), gives about 1.2 × 10²² for ours, "about 65 stars to a well at every level"; the Star Existence Condition, m_P/m_p > α^(−1/2), makes stars stand only above L ≈ 22.2. BPT Part 3.14's Game's Reading fixes how each kind is drawn: "Stars are drawn by type: blue-white giants bright and few in young clusters, red giants and supergiants large and orange, red dwarfs small and dim, brown dwarfs fainter still, white dwarfs as small sharp points, neutron stars blinking as pulsars; supernova remnants and planetary nebulae as expanding shells." BPT Part 3.11 adds that "space holds a floor of starlight, a void a tenth or more of the mean". How many stars each drawn star stands for is Chapter 5's starMult.
The established physics
- Stars orbit their cluster's mass at the Kepler rate, ω = √(G·m/r³).
- Light adds, and the eye reads it by its logarithm: the magnitude scale makes five magnitudes a factor of 100 (Pogson 1856), one magnitude 10^0.4.
- Voids hold 10 to 20 % of the mean density (Sheth & van de Weygaert 2004), cited in the code.
- A star's color follows its temperature (Planck 1900); its size on the sky here is a picture of its light, not its radius.
- About one pulsar in several sweeps its beam past a given observer; the game's one in five is a choice the code does not source.
The game's math
How many points. setMatter(matter, merges, clusters, colourAt, wells) scene3d.js:697 draws matter.js's bodies:
STAR_MAX = round(pointBudget, or 30,000 before one is set) (Part 8.8)
STAR_BODY = 4,000
M = Σ body masses
q = max(0.05, M / STAR_MAX) (matter per drawn point)
points(b) = max(1, min(STAR_BODY, round(m_b / q)))
So the sky holds at most about STAR_MAX points, each an equal share of the matter; a body never has more than 4,000; and while the whole matter is under 0.05·STAR_MAX, a unit of mass is never more than 20 points. A body inside a drawn galaxy (inGalaxy() scene3d.js:690, a hash of 16 × 16-cell bins) keeps only its gas, white dwarfs and neutron stars: its stars are drawn by the galaxy layer of Chapter 6.
Where. Each body's points are scattered by its own seed (starCache, scene3d.js:729–751), kept until its count changes: point 0 at the center, the rest at r = rad·u^1.6 with rad = 0.5 + 0.6·√(m/π) cells, the area its matter fills. placeMatter(frac) scene3d.js:1017 lays each at its body's cell plus its own offset, turned by its orbit, plus frac of the step's motion, converted from true lengths to cells by the local cell sizes of the equal-area map (wider round the outside of the ring, longer down the tube near the throat, the same area), and 0.03 above the skin.
Orbits. Each point circles its body's mass at its own Kepler rate (scene3d.js:794–799):
ω = sense · min(0.6, √(G_k · m / r³)) radians a flip, r = max(0.35, its distance in cells)
G_k = matter.G · matter.gk (the universe's G, diluted by the expansion; Chapter 4)
sense = the body's own spin S (matter.js), else the universe's
What each point is (scene3d.js:756–788). A body's points are its stars first, its gas after: the star share is 1 − gas/m of its points, brightest stars first; a lone point is a star only if the body holds one at least as bright as the Sun. A star's color and size come from starLook() scene3d.js:661 by its kind (typeOf, stars.js): a tint on white, 0.3 to 0.35 of the type's color, giants and supergiants orange and swollen (0.06 and 0.1), O, B and blue giants 1.35·(0.018 + 0.012·log₁₀(1 + L)) up to 0.12, M dwarfs 0.014 at 0.85 brightness, brown dwarfs magenta at 0.45, white dwarfs 0.011 and neutron stars 0.009. The gas is a haze: large (0.075 + 0.035·min(1, gas/64)), faint (0.025 + 0.04·min(1, √(gas/32)) of the data's color), so it adds to a glow where it gathers. One neutron star in five blinks as a pulsar, period 0.25 + 1.2·(h mod 997)/997 s, bright for 12 % of it.
The light each stands for. standLight(starMult) scene3d.js:684: with lg = log₁₀(starMult), each decade a drawn star stands for adds 0.15 to its size and 0.1 to its brightness (the Pogson logarithm); setMatter holds the gain at 1.3 times the brightness and 1.25 times the size (scene3d.js:776) so a deep universe's clumps do not pile into white. At level 28 starMult ≈ 1.7 and the stars are nearly single points; at level 133 it is about 5 × 10¹⁰.
The starlight skin (paintStarlight() scene3d.js:890, every third step). Because points cannot show 10²² stars, each field cell of a second texture glows by the real stars it holds:
N_cell = Σ stars s.n · starMult + 0.12·(mean N) (a void's floor, Sheth & van de Weygaert)
light = Σ s.n · L(s) · color(s)
blur : a box of radius max(1, round(3·cols/256)) three times each way (about a Gaussian)
b = clamp((log₁₀(1 + N_cell) − 6) / 15, 0, 1)^1.2 (nothing at 10⁶ stars, full at 10²¹)
pixel = 0.45·b·(0.6·light/max + 0.4·warm) + 0.32·gas glow·blue
and starSkinMaterial() scene3d.js:847 scatters tiny stars over it on three grids, 1024 × 512, 2048 × 1024 and 4096 × 2048 places across the torus, each place holding a star with chance dens = clamp(2.4·L_pixel, 0, 0.92), each held as a bright pixel down to half a pixel's cell and fading into the glow below that. With every place filled the three grids hold 0.92 × 11,010,048 ≈ 1.0 × 10⁷ stars.
Flashes and disks. A merger, supernova or planetary nebula flashes where it happened (stepFlashes() scene3d.js:1049) for 8, 16 or 10 flips: a merger warm, sized by min(1, log₂(1 + m/4)/7); a supernova a shell growing as 0.06 + 0.5·√x, white-hot to blue-violet; a nebula soft teal. Up to 600 are pushed a step and 128 kept. setBodyDisks() scene3d.js:989 gives the 160 heaviest bodies above matter.full an accretion disk, 0.08 + 0.05·log₂(1 + m/64) across times √scale, bluer round a planet, turning at 0.6 + min(2, 0.02·|S|) radians a second. Before the starlight skin, dense 8 × 8-cell patches above 2.5 times the mean drew as cluster glows (scene3d.js:821–837); the skin replaced them.
In the game
At the Physical Nova the matter flies out with the torus from the pin head, and from then on the skin is covered in points of light gathered round the bodies of matter, each point circling its body's mass at its own Kepler rate, so clumps visibly turn. The points take the color of the data they condensed from (with "Colour by" on "Data lineage", index.php:189), so the colors painted into the Pulsecore at the start are still on the sky at the end: BPT's physical as the data seen at the Tempo. Among them the kinds of star are told apart as BPT Part 3.14 lists them: blue-white giants large and bright, giants and supergiants swollen and orange, red dwarfs small and dim, brown dwarfs faint magenta, white dwarfs small sharp points, neutron stars tiny, one in five blinking as a pulsar. Gas is a faint bluish haze that brightens where it gathers. Mergers flash warm, supernovae leave white-hot shells cooling to blue-violet, planetary nebulae soft teal shells; heavy bodies wear small turning disks. Under the points the starlight skin glows where the real stars are many, with tiny stars scattered over it, and a faint floor of light in the voids.
The "Stars:" readout gives the true level's count, every drawn star times starMult: … shining · O … B … A … F … G … K … M … · brown dwarfs … · giants … · white dwarfs … · neutron stars … · supernovae … · stellar wells … (starLine() stars.js:254). Before the first star it reads "none yet · the gas is still too warm to collapse"; before the Physical Nova "none before the Physical Nova"; and at a level below the Star Existence Condition "none: gravity outweighs the electric force between protons at this level" (app.js:2145), the tooltip naming "book Parts 2.9 and 6.10" (index.php:86). The epoch line counts the living stars, Universe · expanding, …% of its final size · … stars. The "Level L" slider is the player's control over all of it: below about 23 the universe holds matter and wells but no stars; deeper levels have more stars, each drawn point standing for more.
The scale model
This is the main scale model of the drawing. The universe's stars, starMult of them per drawn star (Chapter 5), are drawn as about STAR_MAX points (Part 8.8), each an equal share q of the matter, a body at most 4,000; the light of all the stars each point stands for is shown by its size and brightness on a logarithm; and the starlight skin shows the real count per cell from 10⁶ to 10²¹, with up to ten million tiny stars over it. A level 28 universe on a desktop draws up to 16,000 points, each about 1.7 stars; a level 133 universe draws the same number, each about 5 × 10¹⁰.
Where the game and the theory differ
- The light each point stands for follows the Pogson logarithm only for a while: the brightness gain stops at 1.3 (starMult = 10³) and the size gain at 1.25 (starMult ≈ 46), so at level 133, about 5 × 10¹⁰ stars a point, a drawn star is no brighter than at level 40.
- BPT Part 3.14 has every neutron star seen from a beam's path blink as a pulsar; the game blinks one in five, a fraction the code does not source.
- A body is drawn with up to 4,000 points, the starlight skin with up to about 10⁷ tiny stars, 128 flashes and 160 body disks at once; the counts BPT gives (about 1.2 × 10²² stars at level 202) are carried by starMult and the readout, not by the points.
Fixed numbers
| Number | Where | What it is | Kind |
|---|---|---|---|
| 30,000 | scene3d.js:703 | STAR_MAX before a point budget is set | CAP |
| 4,000 (STAR_BODY) | scene3d.js:703 | points per body | CAP |
| 0.05 | scene3d.js:707 | least matter per point (at most 20 points per unit mass) | CAP |
| 2048, 1.4 | scene3d.js:712 | point buffer floor and headroom | METHOD (allocation, not a limit) |
| 16 cells | inGalaxy() scene3d.js:692 |
bin size of the galaxy hash | METHOD (spatial hashing) |
| 0.5, 0.6, 1.6, 4, 8 | scene3d.js:735 | a body's spread (√(m/π)) and heaviness | DISPLAY |
| 0.55, 0.08, 0.35, 0.7, 0.75, 0.2, 0.04, 0.6, 0.5, 0.3, 0.35, 0.55, 0.035, 0.075, 0.02, 0.018 | scene3d.js:743–748 | point hues and sizes, data color share | DISPLAY |
| 512, ×2 | scene3d.js:806 | cache prune | METHOD (memory) |
| 0.6 rad a flip | scene3d.js:798 | top orbital rate | METHOD (no wheel strobes backward) |
| 0.35 cells | scene3d.js:798 | least orbital radius | METHOD (softening) |
| √(G·m/r³) | scene3d.js:798 | Kepler rate | PHYSICS (Kepler's third law) |
| 20 (gas quantum) | scene3d.js:758 | gas share rounded to 1/20 before recoloring | METHOD (recolor only on change) |
| 1 L_☉ | scene3d.js:763 | a lone point is a star only as bright as the Sun | DISPLAY |
starLook() tints, sizes, 0.3–0.65, 8 M_☉ |
scene3d.js:666–674 | kinds of star | DISPLAY |
| 0.55, 1.3, 1.25, 1.15 | scene3d.js:776, 784 | brightness and size caps on the light boost | DISPLAY |
| 0.025, 0.04, 32, 0.075, 0.035, 64, 1.12, (0.5, 0.56, 0.85) | scene3d.js:780–782 | gas haze | DISPLAY |
| 1 in 5 (h mod 5) | scene3d.js:800 | pulsars that blink | DISPLAY (no source given) |
| 0.25, 1.2, 997, 1000, 0.12, 0.05, 0.009 | scene3d.js:1043 | pulsar period and flash | DISPLAY |
| 0.15, 0.1 per decade | standLight() scene3d.js:687 |
light of the stars stood for | PHYSICS (Pogson 1856, logarithmic response) |
| 3 (every third step) | scene3d.js:908 | starlight repaint interval | METHOD (it changes slowly) |
| 0.12 | scene3d.js:922 | void floor of the mean | PHYSICS (Sheth & van de Weygaert 2004, 10–20 %) |
| 3·cols/256, 3 passes | scene3d.js:924–928 | blur radius and passes | METHOD (box blur approximating a Gaussian) |
| 6, 15, 1.2, 14, 0.32, 0.45, 0.6, 0.4, warm and blue tints | scene3d.js:932–937 | starlight brightness range and color | DISPLAY |
| 1024 × 512, ×2, ×4 | starSkinMaterial() scene3d.js:849, 868 |
grids of skin stars, at most about 10⁷ | CAP |
| 2.4, 0.92, 0.004 | scene3d.js:866–868 | chance of a star per place | DISPLAY |
| 2.2, 0.5, 0.07, 0.12, 0.6, 0.35, 0.6, 1.4, 0.85, 0.7, 0.2, hash constants | scene3d.js:855–867 | skin star size, fade and color | DISPLAY |
| 8, 16, 10 (FLASH_LIFE) | scene3d.js:18 | flash life in flips | DISPLAY |
| 600 | scene3d.js:815, 1051 | flashes pushed a step and buffer | CAP |
| 128 | scene3d.js:816 | flashes kept | CAP |
| 4, 7, flash sizes and colors | scene3d.js:815, 1058–1062 | flash strength and look | DISPLAY |
| 160 (MAX) | setBodyDisks() scene3d.js:990 |
bodies with a disk | CAP |
| 64 (matter.full fallback), 6 (planet bound) | scene3d.js:997–998 | heavy enough for a disk; a planet | DISPLAY |
| 0.08, 0.05, 64, 0.6, 2, 0.02, 0.02 lift, colors | placeBodyDisks() scene3d.js:1009–1011 |
disk size, turn, lift | DISPLAY |
| 8 × 8, 2.5, 256, 4, glow colors | scene3d.js:825–835 | cluster glows (now off under the starlight skin) | METHOD (patch size, threshold) and DISPLAY |
| 600 (uScale start), 0.9·h, 2.5, 1.5, 0.18, 0.5, 0.55, 1.6 | starMaterial() scene3d.js:460–462, 1949 |
point size on screen, core and halo | DISPLAY |
| 3600 ms, 2, 1.4, 0.4, 0.3, 0.45, 0.25, 0.7, 7.31, 3.17, 0.6 | placeMatter() scene3d.js:1025–1038 |
the unused fly path | DISPLAY (dead code) |
| 0.03 | scene3d.js:1020 | stars above the skin | DISPLAY |