- packages/db: postgres.js + ioredis wrapper, StateStore interface with InMemory + Postgres implementations, schema migration runner - apps/api: refactored to use @kerbal-rt/db; live WebSocket hub subscribes to store changes and broadcasts to all clients - apps/tools/mock-telemetry: Node script that generates realistic KSP state and POSTs to /api/v1/ingest at 1Hz (uses same keplerian math as the live-map renderer) - apps/hub: new /debug page that connects to /api/v1/live and shows the live state - ksp/README.md: documents Phase 1c (real kRPC bridge) and the two implementation options - Tests: 17 total (5 kepler math, 5 db store, 5 API health/state, 2 API WebSocket fan-out) End-to-end verified: mock publisher → API → hub /debug page, 11 snapshots/5s over WebSocket, vessels advancing in mean anomaly.
4.4 KiB
KSP-side Telemetry Bridge
This directory will hold the bridge between a running Kerbal Space
Program game and the kerbal-rt API. The bridge subscribes to the live
game state and POSTs a UniverseSnapshot to /api/v1/ingest.
Status: Phase 1c — not yet implemented. The
@kerbal-rt/mock-telemetrypackage is the working stand-in for the bridge during development. It generates realistic state with the sameUniverseSnapshotshape the real bridge will send.
Two implementation options
Option A — kRPC (recommended, fastest to ship)
kRPC is the modern, well-maintained RPC framework for KSP 1.12.x. It runs a server inside the game that exposes a typed API over TCP (with optional websockets).
Setup:
- Install KSP 1.12.5 + ckan
ckan install kRPC— pulls in the server mod + protobuf defs- Start KSP, load your save, start a kRPC server (default port 50000)
- Run a small Node client that subscribes to streams:
vessel.orbit(returns a tuple of orbital elements)vessel.situationspace_center.utbody.orbitfor each bodyspace_center.transform_position/rotationfor ground stations
- The client formats a
UniverseSnapshotand POSTs toPOST http://api:4000/api/v1/ingestwith thex-api-keyheader set to yourINGEST_API_KEY
Node client skeleton:
import krpc from 'krpc-node';
// or: import { Client } from 'node-krpc';
const client = krpc.connect({ host: 'localhost', rpcPort: 50000 });
const sc = client.spaceCenter;
// Subscribe to streams (push every 1s)
const ut = client.addStream(() => sc.ut);
const vessels = await sc.vessels;
setInterval(async () => {
const snap = {
ut: ut.get(),
capturedAt: new Date().toISOString(),
activeVesselId: sc.activeVessel?.id.toString() ?? null,
bodies: await buildBodies(client),
vessels: await Promise.all(vessels.map(v => buildVessel(client, v))),
groundStations: await buildGroundStations(client),
};
await fetch('http://localhost:4000/api/v1/ingest', {
method: 'POST',
headers: { 'content-type': 'application/json', 'x-api-key': process.env.INGEST_API_KEY! },
body: JSON.stringify(snap),
});
}, 1000);
(There's no official kRPC Node client, but a quick protobufjs setup
using the .proto files from the kRPC mod works in <300 lines.)
Option B — Custom KSP mod (most flexible)
A C# KSP mod that uses Harmony to patch into FlightGlobals and
publishes state on each physics tick. Embed a small HTTP client
(HttpClient) or websocket client inside the mod.
- Pro: Total control, can publish events (stage, maneuver node, collision) not just state. Can disable the publish path with a toggle in the mod's UI.
- Con: You own the codebase forever. Have to maintain it across KSP updates. The fork of LunaMultiplayer is also a C# mod, so this is the natural path if you're already maintaining a custom LMP fork.
When to use this: only if kRPC can't give you the data you need (e.g. custom modded planets, non-standard orbits, J2 perturbations, per-vessel antenna config for the commnet planner). For the stock Kerbol system, kRPC is enough.
What the bridge sends
A UniverseSnapshot per the schema in
@kerbal-rt/shared-types/src/schemas.ts.
The mock publisher's output
(apps/tools/mock-telemetry/src/index.ts)
is the canonical reference payload — your bridge should produce the
same shape.
Running the real bridge
# 1. Make sure KSP is running with the kRPC mod enabled
# 2. Make sure the API is running (Phase 1a)
# 3. Run the bridge (Phase 1c — TBD)
pnpm --filter @kerbal-rt/ksp-bridge start
# (this script doesn't exist yet; see Option A/B above)
Why this isn't done yet
The real bridge requires:
- A real KSP 1.12.5 install with kRPC mod loaded
- A save with vessels, in a state interesting enough to publish
- Iterating on the protocol against the real game (KSP exposes orbital data in KSP-specific frames; you have to translate to the heliocentric ecliptic frame for the API)
We can do all of that, but the value of a working mock-driven pipeline (which the user already has) is much higher than a real bridge sitting unused. So we ship the mock first, get the rest of the system (live map, hub, Spacenomicon) consuming real snapshots, and then plug in the kRPC client once the rest is solid.