terminal-space-program

module
v0.29.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 20, 2026 License: MIT

README

Buy Me A Coffee

Terminal Space Program

Terminal-native orbital-mechanics rocket simulator. A take on Kerbal Space Program that lives in your terminal, distributed as a single static Go binary.

Inspiration

I love Kerbal Space Program, I love TUI Applications. I decided the two should be married for when I'm bored and have a terminal available.

The Game

Orbit rendering in the launch / landing chase-cam view

By default, you spawn in an Apollo-style SIV-B in a 500km circular orbit. Switch targets to Moon (press t to switch and T to clear). Plant a Hohmann transfer + inclination change (press H). Or, fly it all manually. See Controls & flight guide for a quick tour, a launch walkthrough, and the full list of keys.

Plan transfers between planets and moons, fly your rocket off the pad and into orbit by hand, rendezvous and dock, stage away spent boosters, and bring a capsule home under parachute — all drawn with braille-canvas graphics and driven from the keyboard. No mouse required, no GUI, just a single binary in your terminal.

Under the hood it's a real orbital-mechanics sim: gravity, fuel, atmospheric drag, and timing all matter, the way they do in real life. Unlike KSP (without mods), the default game renders our solar system. Launches are hard, they take 7.5km/s for LEO - just like real life. The moon is inclined, the earth is tilted on its axis. To match the real solar systems, there are real life vessels with accurate loadouts of thrust.

Recently introduced: a familiar 1/10th-scale system named Lumen; home to a familiar planet, Kernel, with two moons, Cursor and Glyph - and a nearby red planet, Rust. A Lumen-specific vessel is scaled to that environment. It's a little rough appearance-wise as no textures have ported over to that system, but vessels fly and hit familiar Delta-V marks for launch, Cursor (Mun) transfers, etc. From a default game launch press TAB to cycle through the available solar systems until you reach Lumen. Press F to cycle to the planet Kernel, then press N to spawn a craft there.

Each vessel is bound for its lifetime to the system it spawns in — the simulator flies every vessel against its own system and the camera follows your active vessel's system, so a craft parked in Sol keeps orbiting while you fly in Lumen (TAB stays a browse-only camera toggle). Adding Lumen also changed the body catalog, so the on-disk save format moved to v8; older saves auto-migrate on load.

When your live trajectory is heading into a body's sphere of influence, the orbit map draws the full encounter arc ahead of arrival — entry, perilune, and exit — with a Perilune marker and an always-on SOI PASS chip showing the altitude and time to closest approach. No need to target the body first. Every orbital marker (apoapsis, periapsis, nodes, closest approach, maneuver nodes) is now a single colored glyph: shape is type, color is type, brightness is state (nominal / counterfactual / alarm). To read an encounter up close, press f to focus the body it passes — the camera fits to the body's sphere of influence so the capture curve fills the canvas, and from there the view is yours: +/- zoom holds until you change focus, view, or system.

Recently introduced: an in-game Vehicle Assembly Building (VAB). From the main view press Esc → [Build (VAB)] to design your own rocket from fine parts — compose engines, fuel tanks, command cores, antennas, and structure into stages, stack the stages, mark dock seams for nose payloads, and watch a live Δv / TWR / mass readout as you build. Editing is in place, maneuver-form style: you open onto a stage, press ←/→ on its engine or tank row to swap that part within its kind (the engine leads the stage's chemistry), +/- to add more, and enter on a shipped catalog part (an S-IVB, a Falcon booster) to crack it open into editable components and tweak from there. Set a t Σ Δv target and a tank row will hint how many tanks close the gap. Save a design and it shows up in the spawn form (n) alongside the built-in craft, so you design once and launch many. Designs are portable files under ~/.config/terminal-space-program/designs/ (KSP .craft-style); drop one into the sibling loadouts/ overlay dir to share it as a mod. Multiple engines in a stage combine honestly (thrust adds, Isp is the thrust-weighted blend) and a stage holds a single fuel chemistry, so everything you build flies on the same honest physics as the shipped fleet.

Recently introduced: a multi-save system. Esc → [Save Game] / [Load Game] opens one browser for every save — your named saves (create one with the + New save… row, or overwrite an existing one), plus the managed quicksave lane (F5 to save, F9 to instant-load, no confirm) and three rotating autosaves (a real-time interval, 5 minutes by default and tunable in Settings, plus one on quit). The old single save.json is auto-imported as a named save the first time you launch this version and is left in place, untouched, as a downgrade safety net. Saves are flat, independent files under ~/.local/state/terminal-space-program/saves/ ($XDG_STATE_HOME if set) — no save-schema change, so existing saves load exactly as before.

The visual foundation was lifted (with MIT attribution) from furan917/go-solar-system. See NOTICE.md for the full acknowledgments list.

Install

Homebrew (macOS / Linux)
brew install --cask jasonfen/tap/terminal-space-program
Scoop (Windows)
scoop bucket add jasonfen https://github.com/jasonfen/scoop-bucket
scoop install terminal-space-program
Direct download
# Linux x86_64
curl -L https://github.com/jasonfen/terminal-space-program/releases/latest/download/terminal-space-program-linux-amd64.tar.gz | tar xz
./terminal-space-program

Replace linux-amd64 with linux-arm64, darwin-amd64, darwin-arm64, or windows-amd64 (use the .zip variant on Windows).

No Go toolchain, no libc dance. CGO_ENABLED=0 static binaries.

Build from source
git clone https://github.com/jasonfen/terminal-space-program
cd terminal-space-program
go build ./cmd/terminal-space-program
./terminal-space-program

Requires Go 1.24 or newer.

Command-line flags

By default the game opens with a vessel in low Earth orbit. Flags let you jump straight to a different start — a system, a body to orbit or launch from, an orbit altitude and inclination, or a named launch site:

terminal-space-program --orbit moon --altitude 100km          # 100 km lunar orbit
terminal-space-program --system Lumen --orbit kern --loadout Kern-Stack
terminal-space-program --orbit earth --altitude 400km --inclination 51.6
terminal-space-program --launch-site KSC --loadout Saturn-V    # on the pad
terminal-space-program --list-bodies --system Lumen           # discover names
terminal-space-program --version

--version and the --list-* discovery flags print and exit. See the command-line reference for every flag, units, defaults, and more examples.

Multiplayer (ssh)

Host a shared session straight from your own game — no separate server:

terminal-space-program --serve                 # play AND accept guests (port 23234)
terminal-space-program serve invite dave       # mint a one-time invite code
ssh -p 23234 your-host                         # guests join from any terminal

You can also start hosting from inside a running game — no restart, no --serve: open the O session roster and press h (press it again to stop, which drops guests but keeps everyone's progress).

Guests enroll once with the invite code (their ssh key becomes their identity) and get their own persistent space program on your machine. Everyone warps time independently: other players appear as dim "ghost" craft — with their orbits drawn on your map — evaluated at your clock, and the O session roster shows who's ahead or behind. From that roster, s sync-warps you forward to a player's time to fly formation, and v spectates a player — fitting the camera to their ghost orbit and following it so you can watch their burns play out. Warp clamps, planted burns, and SOI transitions are all honored en route.

Closing the distance takes orbits of coasting, so warp there together: w on a player's roster row arms a rendezvous warp toward your predicted closest approach with them. They get a persistent prompt on their main screen — y joins — and from that moment your warps are rate-locked (slowest wins) all the way to the encounter, planted burns firing en route. Either side cancels with /; if the encounter drifts off the committed approach mid-coast, a warning chip says so. You arrive at closest approach at 1× — already coupled — and slide straight into the final approach.

Once you're together, proximity does the rest: come within 10 km of a player you're synced with and your time-warp couples to theirs, so neither can skip ahead during the approach. Dock your craft to theirs and you fly one shared stack — the guest can U undock their own component at any time, and the pilot can hand the whole stack over with J transfer control.

Custom vehicles

Vehicle loadouts and stage parts are data, not code. Drop a .json file in ~/.config/terminal-space-program/loadouts/ (or under $XDG_CONFIG_HOME) to add your own loadouts and parts, or override a built-in by reusing its id. A loadout is an ordered list of part references; a part is one atomic stage. Run terminal-space-program --list-loadouts to see the merged catalog and confirm yours loaded — a malformed file is skipped with a warning, never failing the rest. See the command-line reference for the format.

Learn more

License

MIT. See LICENSE.

Star History

Star History Chart

Directories

Path Synopsis
cmd
internal
keylayout
Package keylayout maps keypresses between the player's physical keyboard layout and the QWERTY positions every binding is authored against (ADR 0022).
Package keylayout maps keypresses between the player's physical keyboard layout and the QWERTY positions every binding is authored against (ADR 0022).
missions
Package missions defines pass/fail Objectives and the Missions that bundle them, evaluated against the live sim state each Tick.
Package missions defines pass/fail Objectives and the Missions that bundle them, evaluated against the live sim state each Tick.
physics
Package physics implements the spacecraft propagation layer: state vectors, integrators (Verlet + RK4), and patched-conic SOI handling.
Package physics implements the spacecraft propagation layer: state vectors, integrators (Verlet + RK4), and patched-conic SOI handling.
planner
Package planner implements trajectory prediction (predictor) and stubs for Phase 3 maneuver-library work (hohmann, lambert) that slip past v0.1.
Package planner implements trajectory prediction (predictor) and stubs for Phase 3 maneuver-library work (hohmann, lambert) that slip past v0.1.
relay
Package relay is the multiplayer store (v0.27 S4, ADR 0034): a no-physics, no-clock report/subscribe hub.
Package relay is the multiplayer store (v0.27 S4, ADR 0034): a no-physics, no-clock report/subscribe hub.
render
Package render holds the visual constant tables shared across screens — body color palette, UI tier colors for status / nodes / trajectory.
Package render holds the visual constant tables shared across screens — body color palette, UI tier colors for status / nodes / trajectory.
save
Package save persists and restores the simulation World as JSON.
Package save persists and restores the simulation World as JSON.
serve
Package serve hosts the embedded SSH front door for multiplayer sessions (ADR 0034, v0.27).
Package serve hosts the embedded SSH front door for multiplayer sessions (ADR 0034, v0.27).
sessiondir
Package sessiondir is the server-side session directory for multiplayer (v0.27 S3, ADR 0034): a versioned session.json holding the player roster, outstanding invite codes, and the body-catalog hash, plus one save envelope per enrolled player (current save.SchemaVersion).
Package sessiondir is the server-side session directory for multiplayer (v0.27 S3, ADR 0034): a versioned session.json holding the player roster, outstanding invite codes, and the body-catalog hash, plus one save envelope per enrolled player (current save.SchemaVersion).
settings
Package settings holds the player's global UI preferences — currently the default visibility of each orbit-screen Chip — persisted to a standalone settings.json under $XDG_CONFIG_HOME/terminal-space-program/.
Package settings holds the player's global UI preferences — currently the default visibility of each orbit-screen Chip — persisted to a standalone settings.json under $XDG_CONFIG_HOME/terminal-space-program/.
sim
Package sim — v0.11.0+ launch-trail breadcrumb buffer.
Package sim — v0.11.0+ launch-trail breadcrumb buffer.
spacecraft
Package spacecraft holds the Spacecraft type and its mutable runtime state (current primary + state vector + fuel).
Package spacecraft holds the Spacecraft type and its mutable runtime state (current primary + state vector + fuel).
tui
tui/screens
Package screens implements the individual tea.Model screens composed by tui.App: OrbitView (C8), BodyInfo (C9), Maneuver (C20), Help (C9).
Package screens implements the individual tea.Model screens composed by tui.App: OrbitView (C8), BodyInfo (C9), Maneuver (C20), Help (C9).
tui/widgets
Package widgets provides drawille-backed canvas + lipgloss HUD helpers shared by all screens.
Package widgets provides drawille-backed canvas + lipgloss HUD helpers shared by all screens.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL