Mavis aebee77843 phase 1c-extract: typed kRPC service client + SpaceCenter extract
Built the missing piece that connects the ksp-bridge to a real KSP
instance via kRPC. This adds a typed service client on top of the
existing KRPCClient, plus the SpaceCenter-specific extraction logic
that pulls the universe state from a running KSP save.

@kerbal-rt/krpc-client
- types.ts — runtime representation of kRPC Type descriptors
  (TypeCode enum, KrpcType interface, decodeKrpcType, typeName)
- decoder.ts — kRPC value codec: primitive decode/encode, class refs,
  enums, collections (LIST/SET/TUPLE/DICTIONARY), system messages
  (STATUS/SERVICES/STREAM/EVENT/PROCEDURE_CALL). 34 unit tests.
- services.ts — ServiceCache built from KRPC.GetServices() response.
  Lookup by (service, procedure), enum value/name resolution. 12 tests.
- service-client.ts — KrpcServices: high-level invoke-by-name client.
  loadServices() helper to connect + load catalog. 9 integration tests
  with a mock kRPC server.
- schema.ts — added Set/Dictionary/Event/Expression types so the
  decoder can handle system messages without external .proto files.
  Also fixed a bug where 'STREAM' was being encoded as 0 due to
  protobufjs's nested-enum string lookup.

ksp-bridge
- extract.ts — the actual SpaceCenter calls. ~280 procedure calls
  per poll for a typical KSP save (UT, bodies, vessels, then per-body
  and per-vessel class methods in parallel). Build the UniverseSnapshot.
- krpc-adapter.ts — rewrote to use KrpcServices (typed) instead of
  the stub extract function. Supports an optional injected services
  for testing.
- bridge.ts — uses the new ExtractedState type and buildSnapshot.
- index.ts — connects to kRPC; falls back to mock mode if no server.
- convert.ts — backward-compat shim, re-exports from extract.ts.

The ksp-bridge can now talk to a real KSP install. We do NOT need
the kRPC mod's .proto files on disk — the server's GetServices()
response is the source of truth for type info. Documented the full
list of procedures we call, the kRPC value encoding, and the new
architecture in ksp/README.md.

Tests: 119 total, all green. Typecheck and build clean across all 11
projects.

Bonus: fixed an integer-overflow bug in the krpc-client connect()
handshake (was passing 'RPC'/'STREAM' strings to protobufjs; its
nested-enum string lookup silently encodes as 0, which made the
stream handshake send the wrong type. Switched to numeric codes.)
2026-06-02 22:02:26 +00:00

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 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

# 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

pnpm test

Build

pnpm build

Data tier (Phase 1)

The API starts in-memory (in-process StateStore) for development. To wire up the real data tier:

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:checktypechecktestbuild on every push / PR to main. See .github/workflows/ci.yml.

Phases

See kerbalrealtime-clone-plan.md for the roadmap. Quick map:

  • Phase 0 — monorepo, skeletons, docker-compose, CI
  • Phase 1a — persistence layer (Postgres+Timescale+Redis) with in-memory fallback
  • Phase 1b — mock telemetry publisher + WebSocket fan-out + hub /debug page
  • Phase 1c — real kRPC bridge (see 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

# 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:

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.

S
Description
No description provided
Readme 304 KiB
Languages
TypeScript 99.1%
CSS 0.5%
Shell 0.2%