# Kerbal RT A real-time web mirror of a no-warp Kerbal Space Program multiplayer server: mission hub + 3D live solar system map. > **Status: Phase 1 — data pipeline working end-to-end.** > Mock telemetry publisher drives the API, the API stores snapshots, the > hub debug page and the live map both consume the WebSocket. Real KSP > bridge (Phase 1c) is documented and ready to plug in once you have KSP. See [`kerbalrealtime-clone-plan.md`](./kerbalrealtime-clone-plan.md) for the full implementation plan. --- ## Stack | Layer | Tech | | ------------------ | --------------------------------------------------------------------- | | **Hub** | Next.js 14 (App Router) + TypeScript | | **Live map** | Vite + React + Three.js + TypeScript | | **API** | Hono on Node 22 + WebSocket (`ws`) + Zod | | **Shared** | `@kerbal-rt/shared-types`, `@kerbal-rt/orbital-math`, `@kerbal-rt/ui` | | **Data (Phase 1)** | Postgres 16 + TimescaleDB, Redis 7, MinIO (S3) | | **Package mgr** | pnpm workspaces | | **Linter** | Prettier (ESLint coming per-app) | ## Layout ``` . ├── apps/ │ ├── hub/ # Next.js — marketing + calendar + media + /debug │ ├── live-map/ # Vite + Three.js — 3D solar system viewer │ ├── api/ # Hono — REST + WS gateway │ └── tools/ │ └── mock-telemetry/ # Node script that drives the pipeline with fake KSP state ├── packages/ │ ├── shared-types/ # TS types + Zod schemas for every API boundary │ ├── orbital-math/ # Pure keplerian propagation, occultation, transfers │ ├── db/ # Postgres+Timescale+Redis wrapper, StateStore interface │ └── ui/ # Shared React components (Pill, Card, …) ├── ksp/ # KSP-side bridge (Phase 1c) — see ./ksp/README.md ├── infra/ # docker-compose, nginx, grafana, init SQL └── scripts/ # dev.sh and friends ``` ## Quick start ```bash # 1. Install deps pnpm install # 2. Run the three apps in parallel pnpm dev # hub: http://localhost:3000 # live-map: http://localhost:3001 # api: http://localhost:4000 # Or run them individually pnpm dev:hub pnpm dev:map pnpm dev:api ``` > The `dev` script for `live-map` proxies `/api/*` to `:4000`, so the live > map's WebSocket and REST calls work out of the box. ## Tests ```bash pnpm test ``` ## Build ```bash pnpm build ``` ## Data tier (Phase 1) The API starts in-memory (in-process `StateStore`) for development. To wire up the real data tier: ```bash docker compose -f infra/docker-compose.yml up -d ``` This brings up: - **TimescaleDB** on `:5432` (with the full KSP body catalog pre-seeded) - **Redis** on `:6379` - **MinIO** on `:9000` (S3-compatible object store for media) - **pgAdmin** on `:5050` (only if you start with `--profile dev`) ## CI GitHub Actions runs `format:check` → `typecheck` → `test` → `build` on every push / PR to `main`. See `.github/workflows/ci.yml`. ## Phases See [`kerbalrealtime-clone-plan.md`](./kerbalrealtime-clone-plan.md) for the roadmap. Quick map: - [x] **Phase 0** — monorepo, skeletons, docker-compose, CI - [x] **Phase 1a** — persistence layer (Postgres+Timescale+Redis) with in-memory fallback - [x] **Phase 1b** — mock telemetry publisher + WebSocket fan-out + hub /debug page - [ ] **Phase 1c** — real kRPC bridge (see [`ksp/README.md`](./ksp/README.md)) - [ ] **Phase 2** — Live map 3D scene (time controls, focus, eclipses, overpass) - [ ] **Phase 3** — Mission calendar, media, crew, YouTube/Twitch embeds - [ ] **Phase 4** — Spacenomicon tools (delta-v, transfer calculator, etc.) - [ ] **Phase 5** — Admin panel + polish - [ ] **Phase 6** — Production deploy ## Verifying the Phase 1 pipeline ```bash # Terminal 1: API cd apps/api && PORT=4000 USE_IN_MEMORY=1 pnpm start # Terminal 2: mock publisher cd apps/tools/mock-telemetry && MOCK_API_URL=http://localhost:4000 pnpm start # Terminal 3: hub cd apps/hub && PORT=3000 pnpm start # → open http://localhost:3000/debug to see the live state ``` For the WebSocket version, open the hub `/debug` page or use [wscat](https://github.com/websockets/wscat): ```bash npx wscat -c ws://localhost:4000/api/v1/live ``` ## License This project is unaffiliated with Kerbal Space Program, Intercept Games, or Private Division. All trademarks belong to their respective owners.