# Free Trader demonstration

Luke Steuber, 2026. A fullscreen Earth–Moon scene with one recorded finite-thrust
LEO → GEO flight. Open `demo.html`; `index.html` remains the freight career.
The demonstration never loads `game.js` or reads or writes career storage.

## Serve and copy

From the repository root, first verify that the permitted port is free:

```sh
lsof -nP -iTCP:5012 -sTCP:LISTEN
python3 -m http.server 5012 --bind 127.0.0.1
```

Open `http://127.0.0.1:5012/orbit/demo.html`. Stop the server when finished.
Use 5011 only if it is free; do not interrupt another server.

For a preview with `index.html` at its root, copy the **contents of `orbit/`**
into an empty preview directory, then copy `demo.html` over that preview's
`index.html`. Keep `physics/`, `vendor/`, `textures/`, `fonts/`, `sky.js`,
`lines.js`, the demo scripts, CSS, favicon, and documentation beside it.
All references are relative; there is no dependency on the `/orbit/` path.
The copied `index.html` is tested separately from `/orbit/demo.html`.
Serve over HTTP, since modules and the recording worker require it.
Do not overwrite the source career's `orbit/index.html`.

## Flight and provenance

`demo-recording.js` calls the existing `ephem`, `kepler`, `flight`, `stations`
and `planner` modules without modifying their model. It starts a free tug at
`shipAt('leo', 2026-10-07 00:00 UTC)`, with **12,000 kg dry mass, 40,000 kg
propellant, zero cargo, 220,000 N thrust, and 450 s Isp**. The planner solves
one free-flight leg to the GEO reference station. There is no station-kept
hold or docking teleport in this recording.

The visible recording begins 600 seconds before first ignition, after the
initial departure-window wait. Every one of its **905 states** is obtained
by propagation from the original free-flight anchor with the plan's own
integrator tolerances. Spacing is at most 30 seconds on coasts and 4 seconds
inside burns, with exact ignition, cutoff and arrival samples. Fuel is read
from the propagated ship, not the engine's intermediate stage samples.
After passing the arrival capture check, the ship continues in free flight
for 1,800 seconds. Station paths remain the model's reference paths.

Reference Node result, measured 2026-10-08:

| Quantity | Value |
| --- | ---: |
| Departure burn | 445.334558 s |
| Departure ideal engine Δv | 2.457042 km/s |
| Circularization / plane-change burn | 247.024269 s |
| Arrival ideal engine Δv | 2.352937 km/s |
| Total ideal engine Δv | 4.809980 km/s |
| Propellant consumed | 34,516.021029 kg |
| Propellant remaining | 5,483.978971 kg |
| GEO arrival separation | 6.829933 m |
| GEO arrival relative speed | 0.001449592 m/s |
| Arrival osculating eccentricity | 0.000000974363 |
| Arrival osculating semimajor axis | 42,164.125951 km |

These quantities come from the numerical recording, not a mission design
estimate or a real spacecraft. Minor last-digit floating-point differences
between Node and browser engines are expected. Repeated recordings within
the tested engine are identical. Browser event jumps use that browser's
exact integrated boundary times.

## Display, timing and input

Positions are a rigid rotation of three-dimensional equatorial J2000
Earth-centred vectors, at **1 scene unit per 1,000 km**. Earth and Moon radii
use that same scale. Orthographic projection preserves scale across depth;
ship, port and burn markers are enlarged screen-space aids. The velocity
arrow gives direction, with a fixed display length; it is not a velocity
magnitude scale. The dashed path is the complete recorded route; the bright
trail is the already flown portion. Amber diamonds mark ignition positions,
and an amber halo and exhaust appear only during the two burns. The halo
and the ship's burn label keep thrust readable when exhaust lies along the
viewing direction. No potential funnel
or spacetime surface is included.

Playback maps physical intervals to **8 + 18 + 27 + 18 + 5 = 76 seconds**:
low-orbit coast, departure burn, transfer coast, circularization, GEO coast.
The current physical elapsed time and compression factor are shown. Each
burn is displayed for a full 18 seconds. Frame advances are capped at 50 ms
of narrative time, so a slow or suspended frame cannot skip a finite burn;
a slow device may take longer than 76 wall-clock seconds. Backgrounding the
page pauses it. It ends paused and Replay starts from the same recording.
The operating-system reduced-motion preference starts paused; Replay also
stays paused, and focus changes are immediate. Manual events remain usable.

Cubic Hermite interpolation uses integrated positions and velocities
between samples. At 53 checked midpoints, maximum display position error
against direct propagation was **0.0418 m**, and maximum velocity error was
**0.0000263 m/s**. These are bounded display checks, not global accuracy
claims. Fuel interpolates linearly across intervals split at burn boundaries,
matching the model's constant mass flow.

The camera's orientation is fixed. Focus controls capture a view when
selected; playback, burns, arrivals and scrub do not update it. Selecting
Earth, Moon, a visible object label or a named port pauses playback and
changes framing. Normal focus transitions ease over 700 ms; Flight or Reset
view reverses them. Resizing refits the full route or adjusts the selected
view's frustum. No camera drag, spin or event-follow mode is present.

Space toggles playback outside inputs, buttons, summaries and dialogs;
native controls keep their own keyboard behavior. Events select recorded
physics times and pause. Native dialogs close with Escape and return focus
to their opener. All visible controls have at least 44 px targets at the
verified 390 px phone viewport. WebGL failure preserves numerical quantities
and playback/event controls, with a readable recovery message. Missing
scripts also have a readable loading-failure message.

## Model limits and licensing

The existing engine integrates physical equations with documented
approximations: point-mass Earth and Moon, an adaptive Dormand–Prince
integrator, and finite constant-thrust burns. J2 is off. Drag, Sun's tide,
radiation pressure, engine transients and detailed attitude are omitted.
The Moon uses the low-precision Astronomical Almanac series, with roughly
2,000 km along-track and 1,000 km distance uncertainty; lunar frame switching
also introduces a force discontinuity. This demonstration stays near Earth.
Ports are station-kept closed-form paths with invented nodes and phases.
Capture abstracts the final metres within 2 km and 5 m/s. Ideal engine Δv
from the rocket equation is distinct from a change in inertial speed while
gravity acts. This is not a real mission or an engineering-grade ephemeris.
See [PHYSICS.md](./PHYSICS.md) for equations, sources and further limits.

Earth and Moon textures: Solar System Scope, CC BY 4.0, unchanged local
1024 px maps; [provenance and hashes](./textures/PROVENANCE.md).
Existing vendored Three.js: [MIT license](./vendor/LICENSE-THREE.txt).
IBM Plex: [SIL Open Font License](./fonts/OFL.txt).
No downloads, external services or runtime network ephemeris are required.

## Verification

```sh
node orbit/test-demo.cjs
node orbit/test-physics.js
node orbit/test-planner.js
# Reuse installed Playwright and Chromium; no install or browser download:
ORBIT_PLAYWRIGHT=/absolute/path/to/node_modules/playwright \
ORBIT_CHROMIUM=/absolute/path/to/chrome-headless-shell \
ORBIT_BASE_URL=http://127.0.0.1:5012/orbit/demo.html \
ORBIT_PREVIEW_URL=http://127.0.0.1:5012/preview/index.html \
ORBIT_EVIDENCE=/absolute/path/to/external/evidence \
node orbit/test-demo.cjs --browser
```

The standalone model checks cover deterministic recording, actual burns and
arrival, fuel flow, rocket equation, orbital energy, exact event boundaries,
interpolation against direct propagation, and independent two-body coast
energy conservation. Browser checks cover desktop and 390 px touch
emulation, deliberate and reversible focus, complete foreground playback of
both finite burns, invariant event/playback camera, Space, native dialogs and
focus restoration, reduced motion, scrub/replay, zero career storage access,
relative-path preview copy, missing-module recovery and unavailable WebGL.
Screenshots and measured results go outside the checkout.

Physical phone ergonomics, Safari/WebKit, screen-reader behavior, sustained
thermal performance and deployment are separate, unverified acceptance
steps. Browser smoke and source checks do not establish WCAG conformance.
