A real-time, terminal-based solar system simulator written in Rust. Planetarium streams ephemeris vectors from the JPL Horizons API, interpolates smooth orbits, and renders them with Ratatui’s Braille canvas so you can watch the planets glide across your terminal in sync with UTC.
- Live ephemeris: Fetches high-resolution vectors for the major planets (Sun → Neptune) and refreshes them every few hours to stay aligned with reality. A local cache keeps previously downloaded data for offline restarts.
- Real-time clocking: The coordinator measures actual wall-clock delta each frame so the simulation advances exactly as fast as real life unless you override the multiplier.
- Spline + physics pipeline: Cubic Hermite splines (seeded with the exact Horizons velocities) provide smooth interpolation between daily vectors, while an RK4 integrator can keep bodies moving when data is missing.
- Camera & TUI renderer: 3D world coordinates are projected into terminal space with aspect correction, then drawn via Ratatui using Braille markers for dense plots.
- HUD & Help overlay: A persistent status panel shows pause/live state and the current time-scale multiplier, while
Hbrings up a control cheat sheet at any time (andLinstantly snaps the sim back to “Live” and forces a Horizons refresh).
- Rust 1.74+ (stable toolchain recommended) with
cargo. - Internet access to reach the JPL Horizons API, unless running in mock mode.
- A UTF-8 capable terminal (Ratatui uses Unicode Braille characters).
git clone https://github.com/ahenkes1/planetarium.git
cd planetarium
cargo build --releaseThis produces target/release/planetarium.
cargo run --releaseThe application will:
- Load any cached state (camera position, current time, ephemeris cache).
- Request ±2 hours of data around “now” for each body, filling gaps only when needed.
- Continue fetching fresh vectors every ~3 hours in the background.
Use the environment variable or CLI flag if you need deterministic offline data (a static Mars sample):
PLANETARIUM_MODE=mock cargo run
# or
cargo run -- --mockSimulation state is saved as JSON under your platform’s config directory (via directories::ProjectDirs). It includes:
- Cached ephemeris vectors per body.
- Current simulation time.
- Camera position.
- Simulation-speed multiplier and last refresh timestamp.
Delete that file if you want a fresh start.
| Key | Action |
|---|---|
Space |
Toggle pause/resume (returns to 1× when resuming). |
F |
Double the simulation speed (clamped to 10000× real-time). |
S |
Halve the simulation speed (down to 0). |
L |
Jump back to Live (reset to real-time clock + trigger a Horizons refresh). |
H |
Toggle the help overlay. |
+ / = |
Zoom camera in (move closer to the target). |
- |
Zoom camera out. |
| Arrow keys | Pan the camera target horizontally/vertically. |
C |
Center camera on the Sun. |
O |
Cycle orbit focus (Mercury → Neptune) with auto-zoom. |
Q or Ctrl+C |
Quit. |
The HUD (top-left) constantly displays whether the sim is paused and the exact time-scale multiplier (e.g., “Live (1×)” or “4.00×”).
If you fast-forwarded or paused for a long stretch, press L to snap the simulation clock back to real-world UTC. This shortcut also kicks off an immediate Horizons fetch for every tracked body (mock mode included), so the splines are reseeded with fresh position and velocity vectors. The HUD briefly returns to “Loading…” while that refresh completes.
The project follows an “actor” mindset with five major agents (see AGENTS.md for details):
- Coordinator – The main Tokio task that drives the event loop, measures frame deltas, and dispatches work.
- Ephemeris Provider – Fetches/normalizes Horizons data, handles retries, and feeds results back via channels.
- Physicist – Maintains RK4 propagation and spline interpolation utilities.
- Cinematographer – Camera math and projection utilities.
- Renderer – Ratatui widgets, HUD/help overlays, and overall TUI composition.
# Format all Rust sources
cargo fmt
# Run tests (unit + integration)
cargo testWe keep files short and focused (many modules under src/). If you add a new feature, prefer creating a dedicated module plus tests alongside it.
- No planets visible: Planets appear as colored symbols (
*) once ephemeris data loads. If you only see orbits, the simulation time may have drifted outside the data window—restart the app or delete the cached state to reset. Use arrow keys to pan or-to zoom out. - Stale data: Delete the cached
state.json(under~/.config/planetarium/on Linux) or wait for the refresh task (~3-hour cadence) to pull new vectors. - API/network errors: The HUD will stay in "Loading…" state. Try mock mode to verify the UI without network access.
Planetarium is distributed under the GNU Affero General Public License v3.0 (AGPLv3). If you modify and run the simulator—especially when exposing it to others over a network—you must provide access to the corresponding source code of your deployed version. See LICENSE for the complete terms.