Physics state
What stays real
a = G * source_mass / distance^3 * displacement
Double-precision positions, velocities, masses, and radii stay in physical units inside src/sim.
C · raylib · WebAssembly
This is a small, physics-first C project: Newtonian gravity in SI units, parent-relative moons, persistent trails, and a raylib renderer compiled to the browser.
Not to scale. The real state lives in meters; this sketch only makes the implemented catalog visible.
Why this exists
The interesting part is the boundary between math and picture: the simulator keeps bodies in meters, kilograms, seconds, and meters per second, then deliberately bends only the rendered view so planets, moons, labels, and trails remain readable.
Simulator
The embedded app below is the WebAssembly artifact from the build pipeline. Use it as a working lab bench, then jump into the docs when you want to see how the physics and rendering are separated.
Physics state
a = G * source_mass / distance^3 * displacement
Double-precision positions, velocities, masses, and radii stay in physical units inside src/sim.
Rendered view
Illustrative scale, moon separation, labels, camera focus, and trails are renderer choices, not changes to simulation state.
Trace the simulation coreBodies in the scene
Moons are initialized relative to their parent body, then added to the same shared gravity simulation.
Current state
Source references
src/sim/physics.c02Body catalogStable BodyId and parent metadata keep renderer, labels, and docs aligned.src/sim/solar_system.c03Rendering boundaryraylib conversion handles readable scale without mutating physics state.src/render/renderer.c04WASM pipelineEmscripten artifacts are checked before Astro publishes them.tools/check_wasm_artifacts.py05Astro docsThe dedicated docs section explains the code as a maintained public notebook.docs/src/pages/docs/