Pilot Matter Docs Play

Simulator API

The simulator is two halves that can be used without each other, and js/api/index.js is the one module a host page imports to get either.

The full reference

This page is the overview. Every option and everything that comes back, for both halves, is written out in the API reference: the contracts, the configured start, the runways and the landing rules, the game modes, the worlds and the elements, the day and the water, what the stability guarantee does and does not cover, and a worked host page for each half.

The Pilot API

The Pilot API is the aircraft: the flight model, the controls, and the telemetry, flown against a scene, a terrain, and an aircraft model the host supplies.

import { createPilot } from './js/api/index.js';

const pilot = createPilot({
    scene,                                  // your scene
    camera,                                 // optional, placed behind the aircraft
    aircraft: myModel,                      // any Object3D, or a loader result
    anchor: { x: 0, y: 0, z: 0 },           // the point in it the flight model moves
    terrain: {                              // your world, or none for flat ground
        sampleHeight: (x, z) => myHeightAt(x, z),
        bounds: { minX: -5000, maxX: 5000, minZ: -5000, maxZ: 5000 }
    },
    keymap: { yawLeft: ['KeyZ'] },          // remap what you like, keep the rest
    flight: { sensitivity: 1.5 }            // how hard the controls bite, 0.1 to 4
});

function frame(dt) {
    const { airspeed, altitude, verticalSpeed, heading, throttle } = pilot.update(dt);
    myHud.render({ airspeed, altitude, verticalSpeed, heading, throttle });
}

The Matter API

The Matter API is the world: an assembled environment as one detachable group, a height sampler for whatever is flying over it, and a contract any aircraft can satisfy, including one driven by a control API that has never heard of this one.

import { createEnvironment } from './js/api/index.js';

const world = createEnvironment({ environment: 'lakeside', runway: true });

scene.add(world.group);
world.applyDepth(scene);                    // the sky and the fog, without the ground
world.register(myWindsock, { x: 400, z: -900 });  // set down on the ground, not over it

const flown = world.attach(myAircraft);     // throws with every gap in the contract
myFlightModel.setGroundHeight(flown.groundHeight());

world.runways[0];                           // the strip it cut, for something to land on
world.setEnvironment('dune-sea');           // regenerated in place, registered assets settled

world.setDaylight(0.75);                    // dusk: the sky, the fog, and the sun with it
world.updateWater(dt, 0.5);                 // and the surface moved on by a frame

An assembly of squares

A world can be one square of a larger one, and createTiledEnvironment builds the whole grid with every join already settled:

import { createTiledEnvironment } from './js/api/index.js';

const world = createTiledEnvironment({ environment: 'lakeside', tiles: 2, size: 8000 });

scene.add(world.group);
world.sampleHeight(x, z);                   // answered by whichever square the point is over

The pure half

Everything under js/api/contract.js is pure and imports no renderer, so a host can check its own options, its own aircraft, or the shape of its telemetry with nothing loaded:

import { validateAircraftContract, TELEMETRY_FIELDS } from './js/api/contract.js';

const problems = validateAircraftContract(myAircraft);   // every gap at once, or []

The rules the bundled game is played by are published too, and they are pure as well: the touchdown rules that tell a landing from a crash, the strips they are read against, and the modes, stages, courses, and gate test in js/game-modes.js. A host can play them against its own renderer, or read them as a worked example of a game built on the two halves.

The worked example

examples/host.html is a host page, running. It works both halves side by side - the Pilot API flying over ground the page generated itself, and the Matter API carrying an aircraft the page built over an assembly of four squares, running the day and moving its own water - which is the shortest way to see that each half genuinely works without the other. Serve the project and open /examples/host.html:

npm run serve   # then open http://localhost:8080/examples/host.html