- C# 38.9%
- JavaScript 33.9%
- TypeScript 27.1%
- Shell 0.1%
The bridge takes POST /flight/timewarp with a modeIndex; the value comes back one lower than requested, so 5 gives the 25x the trace records and higher modes reach 100x. Warp is refused outright while the craft is on an impact course, which is a useful signal in its own right: a vehicle that cannot warp is not in an orbit. Applied only on unpowered coast above 60 km and dropped back to normal well before the burn, because the program aboard waits in half-second steps and those become tens of seconds under warp — long enough to sail past a burn start. Best trajectory yet: periapsis -310 km, apoapsis 296 km, eccentricity 0.239, with the prograde error settling to about 10° through the burn. The mechanism is finally right — apoapsis holds at 209 km while periapsis climbs steadily from -1271 km — and it stopped because the propellant ran out, with periapsis rising about 100 km per five seconds of burn at cutoff. Enlarging the upper stage to buy those seconds made it worse rather than better (apoapsis 1586 km, periapsis -1155 km): the heavier stage changes when staging happens, and the ascent loop then overshoots its apoapsis target badly between polls. Reverted. Run-to-run variance is still large, from -310 km to -1026 km on the same configuration. |
||
|---|---|---|
| .claude-plugin | ||
| catalog | ||
| mcp | ||
| mod | ||
| scripts | ||
| skills/juno | ||
| .gitignore | ||
| GOAL.md | ||
| LICENSE | ||
| package-lock.json | ||
| package.json | ||
| README.md | ||
JunoClaude
A Claude Code plugin for Juno: New Origins (SimpleRockets 2): building craft, writing Vizzy flight programs, launching and reviewing test flights.
It has two parts:
- The plugin — a skill and an MCP server that work directly on the game's files. It works right away, with nothing else to install.
- The bridge mod (
mod/) — an HTTP server inside the game for live telemetry and flight control. Building it requires Unity 2022.3.62f3; seemod/README.md.
Installation
git clone <repo> junoclaude
cd junoclaude
npm install && npm run catalog # part and block catalogs
cd mcp && npm install && npm run build
Then add the directory as a Claude Code plugin.
The game's paths are detected automatically on macOS and can be overridden with
JUNO_INSTALL_DIR, JUNO_USER_DIR, JUNO_LOG_PATH.
Tools
| Tool | Purpose |
|---|---|
game_state |
Installation, whether the game is running, settings, mods |
craft_list |
List of craft |
craft_read |
Summary, part tree, or XML of selected parts |
craft_build |
Build a craft from a declarative spec |
part_lookup |
Part types, attach points, connection recipes |
vizzy_read |
Flight program in the compact DSL |
vizzy_write |
Compile the DSL to Vizzy XML and write it |
game_launch, game_quit |
Control the game process |
log_read |
Errors from Player.log with stacks |
junoclaude_restore |
Roll back to the snapshot taken before a write |
How it works
The game's formats are undocumented, so what we know about them was mined from files the game wrote itself rather than reasoned out:
scripts/build-parts-catalog.mjsextracts the definitions of 70 part types fromSimpleRockets2_ModTools.unitypackageand classifies the attach points;scripts/mine-connections.mjscounts the frequencies of attach point combinations across 61 stock craft and sorts them by kind of connection. This turned out to be necessary: the most frequent recipe for aFuselage1→Fuselage1pair is not a stack connection at all, but attachment to a side surface;scripts/mine-vizzy-blocks.mjscollects the realstylestrings for 45 Vizzy instructions and 67 expressions.
The catalogs are committed to the repository, because installing the plugin does not run the build.
Verified against the running game
The following was checked against the game itself, not inferred:
- Round-trip fidelity. Parsing and re-serializing reproduces the original
file byte for byte: 62 of 62 craft, 5 of 5 subassemblies, 7 of 7 flight
programs. That is, the model loses no attribute of anything we generate.
Differences remain on the stock
GameState/FlightStatefiles, which contain empty tags of the form<X></X>; those files are edited by targeted replacement rather than by rebuilding the tree. - The fuel capacity formula. Derived statistically from 2286 tanks and then
confirmed:
capacity = 550 × utilization × length × cross-section area, where the area interpolates betweenπ·a·b(round cross-section) and4·a·b(square). The round/square ratio came out at exactly 4/π. For the same tank the generated value is 8639.379797 against the game's own 8639.3798828125. - Modifiers are mandatory. If a part type declares a modifier it must be
present in the XML; the game does not fill in defaults. A
CommandPod1without its<FuelTank>fails to load with aNullReferenceExceptioninCraftFuelSources.Rebuild. - Rigid body splits. A body must split before a detachable part, and body mass must not be zero — a zero-mass body makes the game spawn the craft below sea level.
- The craft list is not cached. A craft written while the game is running shows up in the designer immediately.
- The attach-point resolver is correct. The game did not alter any connection in a generated craft, including two that the builder had flagged as heuristically inferred.
- The bridge mod works. The game loads it, the HTTP server answers with
token auth, and a stock rocket was launched and flown through it: altitude
230 m → 1307 m, vertical speed +122 m/s, TWR 1.59 → 1.82. This requires
Run In Backgroundenabled in the game settings, otherwise Unity freezesUpdatewhile unfocused and the bridge times out.
Safety
The plugin writes into the game's save directory, so:
- every write is preceded by a snapshot in
.junoclaude-backups/, rolled back with a singlejunoclaude_restorecall; - files the game rewrites itself (
GameStates/,Settings.xml,Career/) are not editable while it is running. Craft and flight programs are, since the craft list turned out not to be cached; - writes are atomic — the game never sees a half-written file.
Status
Working: the catalogs, reading craft, craft_build, the Vizzy compiler and
decompiler, launching the game, log parsing, snapshots and rollback, and the
bridge mod with live telemetry and flight control.
Known gap: craft_build lays the stack out from zero upward, while the game
expects the origin to sit at the center of mass. A generated craft therefore
spawns misaligned and topples. The rule is established — shift every position by
minus the center of mass — but not yet implemented. Stock craft launch and fly
correctly through the bridge.
Not started: scenario_create (spawning at a launch site or directly in orbit),
and wings in craft_build — Wing1 is a twelve-parameter procedural surface
that does not compose with a linear stack, so use {kind: "raw"} meanwhile.
The bridge exposes one endpoint as deliberately unsupported: targetHeading
returns 501, because the game models it as an orientation quaternion rather
than a scalar heading, and the correct construction was not documented. Writing
a plausible-looking quaternion would have steered craft blindly.
Requirements
- macOS, Juno: New Origins 1.3.205 (Steam)
- Node 20+
- For the bridge mod: Unity 2022.3.62f3 exactly — the version is enforced by ModTools — with Mac and Windows Build Support (Mono)
- Enable
Run In Backgroundin the game settings, or every bridge request times out while the window is unfocused
License
MIT