# Macrostep 08 — Spherical backend ## Objective Implement SmoothLife on a closed sphere with a tested corrected default and one coherent retained `SphereModel::Legacy`, backed by CPU oracles, GPU simulation, and a modern raylib renderer. ## Dependencies Macrosteps 00–06 complete. Macrostep 07 is not technically required, but execute in index order for a single team. ## Phase 8.1 — Cube-sphere geometry model ### Substep 8.1.1 — Face frames and directions Define six typed face frames with a single orientation table. For each face-cell center: ```text direction = normalize(normal + tan(uπ/4)*axis_u + tan(vπ/4)*axis_v) ``` Use configurable `K`, with legacy `K=128` and internal `R=K/2`. Store direction, area, face, and coordinates in CPU structures; upload immutable geometry once. ### Substep 8.1.2 — Cell areas Compute each spherical quadrilateral area from two spherical triangles or a proven equivalent. Test: - every area finite/positive; - face symmetry; - total area approaches `4πR²` within a recorded discretization tolerance. ### Substep 8.1.3 — Seam mapping Implement `SphereModel` as one local enum: - `Corrected` (default): direction-based projection across every edge and corner; materialize and snapshot-test the mapping. - `Legacy`: original 24 side-gutter transforms and invalid corner gutters as one inseparable part of the historical sphere model. Do not expose independent seam/normalization compatibility toggles. Neither model samples and renders to the same atlas; both build a distinct initialized padded sampling atlas from current state. ## Phase 8.2 — Spherical neighborhood oracle ### Substep 8.2.1 — Radius conversion Freeze and implement: ```text ri_planar = ra/3 widths = 1 r_geo = R*acos(clamp(1-r_planar²/(2R²),-1,1)) cap_area(r) = 2πR²*(1-cos(r/R)) legacy search bound = ceil(2ra) corrected search bound = complete nonzero softened support ``` Report invalid chord radii instead of producing NaN. ### Substep 8.2.2 — Direct neighborhood For each active cell: 1. read center direction `a`; 2. visit candidates from the padded atlas/mapping; 3. compute `distance=R*acos(clamp(dot(a,b),-1,1))`; 4. multiply candidate state by candidate spherical cell area; 5. accumulate softened disk/ring weights; 6. normalize according to the selected complete sphere model: - `Corrected`: divide each numerator by the per-center sum of the same `cell_area*kernel_weight` terms actually visited; - `Legacy`: divide disk by `2πR²(1-cos(ri/R))` and ring by `2πR²[(1-cos(ra/R))-(1-cos(ri/R))]`, regardless of softened boundaries or masked corner samples. The CPU implementation may be slow and use reduced `K` for exhaustive tests; clarity and seam correctness are primary. Constant-field uniformity is required for `Corrected`; historical deviations near legacy masked corners are expected fixtures. ### Substep 8.2.3 — Dynamics Both sphere models support only: - discrete replacement `clamp(S)`; - fixed smooth update `clamp(A+0.1*(2S-1))`. Do not expose base relaxation, configurable `dt`, FFT, AB3, or RK4. Future experimental sphere dynamics require a separately named model rather than extending `Legacy`. ## Phase 8.3 — Deterministic initialization Always clear all active and gutter storage. Implement seeded sphere splats with explicit reset versus overlay operations. Provide face-coded, constant, impulse, and great-circle test initializers. Never preserve undefined initial texture contents. ## Phase 8.4 — GPU direct solver ### Substep 8.4.1 — Atlas resources Use separate current, padded-sampling, and next `R32F` targets plus immutable direction/area data. Fill gutters via explicit passes or CPU-generated mapping, then run one direct neighborhood pass over active tiles and swap. ### Substep 8.4.2 — Stencil strategy Start with a bounded GLSL loop specialized/cached by face size and maximum radius. Precompute valid offset metadata where it reduces `sqrt`, branch, or mapping cost without changing semantics. Recompile only on geometry changes, not rule edits. ### Substep 8.4.3 — Parity First compare each CPU model to Macrostep 00's independent source-frozen `M/N/S/next` fixtures at centers, edges, and masked corners for both update modes. Then compare GPU to its validated CPU model. Initial one-step max-error target is `≤1e-3`; CPU/GPU agreement alone is insufficient. ## Phase 8.5 — Sphere presentation Generate one indexed cube-sphere mesh with independent UVs per face. Add: - an explicit `Corrected`/`Legacy` sphere-model selector with a concise semantic comparison; - transactional model switching: construct the complete seam map, normalization data, padded atlas, and shader resources before commit; preserve active-face state and generation when `K` is unchanged; retain the previous model on failure; never share model-specific caches; - orbit/arcball camera and time-based autorotation; - grid overlay; - all shared palettes; - optional two-sided legacy red/blue styling; - active atlas, padded atlas, direction, area, seam, and geodesic-distance views; - face labels and edge-orientation debug mode. Keep rendering geometry separate from simulation resolution so mesh tessellation can change without altering state. ## Phase 8.6 — Verification and performance ### Geometry/seam tests - all 24 directed edge mappings and corner transitions; - cross-edge-and-back round trip; - shared-edge direction equality; - rotational consistency under cube symmetries; - total area and constant-field neighborhoods; - no `acos` NaN. ### Resource tests - no texture feedback; - all gutters explicitly initialized; - framebuffer completeness after rebuild; - repeated `Corrected↔Legacy` switching agrees with a freshly constructed destination model, preserves state/generation, and never mixes seam or normalization caches; - failed switches preserve the previous working model; - rule edits do not rebuild geometry. ### Performance target On the designated GPU, `K=128`, `ra=10` should target p95 step time below 33 ms for both models. If either fails, ship a lower interactive default while keeping `SphereModel::Legacy` selectable and document the measured cost (roughly 165 million candidate iterations per step before optimizations). ## Deliverables - CPU oracles for `SphereModel::{Corrected,Legacy}`. - One coherent retained legacy sphere model, not independent compatibility flags. - GPU sphere backend and raylib sphere renderer. - Sphere-specific inspection and seam diagnostic tools. ## Exit gate - Face orientation, area, edge, and corner tests pass. - Both CPU models match independent source-frozen end-to-end fixtures for both update modes. - Constant state produces uniform neighborhoods for `Corrected`; `Legacy` analytic/masked-corner deviations match committed fixtures. - CPU/GPU one-step parity passes at centers, edges, and corners for both models. - Transactional model-switch lifecycle tests pass without mixed caches or state loss. - Default sphere preset is rotatable, inspectable, and deterministic. - No undefined atlas contents, feedback loop, or unclamped `acos` remains.