Skip to content

Key Events

Key events are high-value computed events that go beyond raw telemetry data. Instead of manually tracking state changes yourself, GameGlue detects significant flight events like landings, takeoffs, and flight phase transitions automatically.

Available Events

EventDescription
landingAircraft touchdown with quality rating and bounce tracking
takeoffAircraft liftoff with rotation speed and configuration
flight_phasePhase transitions throughout your flight

Subscribe to Key Events

Use the same listener.on() pattern you use for telemetry updates:

javascript
// Landing events
listener.on('landing', (evt) => {
  console.log(`${evt.quality} landing at ${Math.abs(evt.landing_rate)} fpm`);
});

// Takeoff events
listener.on('takeoff', (evt) => {
  console.log(`Rotation at ${evt.rotation_speed} kts`);
});

// Flight phase changes
listener.on('flight_phase', (evt) => {
  console.log(`Phase: ${evt.previous_phase} → ${evt.phase}`);
});

No special setup is required. Key events are automatically available on any listener.

Landing Events

Triggered when the aircraft touches down. Includes a quality rating and bounce detection.

javascript
listener.on('landing', (evt) => {
  console.log(`Landing rate: ${evt.landing_rate} fpm`);
  console.log(`Quality: ${evt.quality}`);
  console.log(`Bounces: ${evt.bounce_count}`);

  // Individual bounce details
  evt.bounces.forEach((bounce, i) => {
    console.log(`Bounce ${i + 1}: ${bounce.landing_rate} fpm`);
  });
});

Landing Data

FieldTypeDescription
landing_ratenumberVertical speed at touchdown (fpm, negative = descending)
qualitystringQuality rating based on landing rate
bounce_countnumberNumber of bounces (0 = smooth touchdown)
bouncesarrayDetails of each bounce
pitchnumberPitch angle at touchdown (degrees)
rollnumberRoll angle at touchdown (degrees)
headingnumberHeading at touchdown (degrees)
speednumberGround speed at touchdown (knots)
latitudenumberTouchdown position
longitudenumberTouchdown position
timestampnumberUnix timestamp (ms)

Landing Quality Ratings

QualityVertical Speed
butter< 60 fpm
smooth60-120 fpm
normal120-180 fpm
firm180-300 fpm
hard300-600 fpm
crash> 600 fpm

Bounce Detection

GameGlue tracks bounces during landing using a 3-second stabilization window. If the aircraft leaves the ground within 3 seconds of touchdown and lands again, it's recorded as a bounce rather than a separate landing.

javascript
listener.on('landing', (evt) => {
  if (evt.bounce_count > 0) {
    console.log(`Oops! ${evt.bounce_count} bounce(s)`);
    evt.bounces.forEach((b, i) => {
      console.log(`  Bounce ${i + 1}: ${Math.abs(b.landing_rate)} fpm, airborne ${b.airborne_duration_ms}ms`);
    });
  }
});

Takeoff Events

Triggered when the aircraft leaves the ground.

javascript
listener.on('takeoff', (evt) => {
  console.log(`Rotation speed: ${evt.rotation_speed} kts`);
  console.log(`Pitch at liftoff: ${evt.pitch_at_liftoff}°`);
  console.log(`Flaps: ${(evt.flaps_setting * 100).toFixed(0)}%`);
});

Takeoff Data

FieldTypeDescription
rotation_speednumberIndicated airspeed at liftoff (knots)
pitch_at_liftoffnumberPitch angle at liftoff (degrees)
headingnumberHeading at liftoff (degrees)
flaps_settingnumberFlap position (0-1)
latitudenumberLiftoff position
longitudenumberLiftoff position
timestampnumberUnix timestamp (ms)

Flight Phase Events

Triggered when the flight phase changes. Useful for tracking progress through a flight.

javascript
listener.on('flight_phase', (evt) => {
  console.log(`${evt.previous_phase} → ${evt.phase}`);
  console.log(`Altitude: ${evt.altitude_msl} ft MSL / ${evt.altitude_agl} ft AGL`);
});

Flight Phase Data

FieldTypeDescription
phasestringCurrent flight phase
previous_phasestringPrevious flight phase
altitude_aglnumberAltitude above ground level (feet)
altitude_mslnumberAltitude above mean sea level (feet)
speednumberGround speed (knots)
timestampnumberUnix timestamp (ms)

Available Phases

The flight phases follow a typical flight progression:

PhaseDescription
parkedOn ground, engines off or idle, no movement
taxi_outOn ground, moving toward runway
takeoff_rollOn runway, accelerating
initial_climbJust lifted off, < 1000ft AGL
climbClimbing, altitude increasing
cruiseLevel flight at altitude
descentDescending, altitude decreasing
approach< 3000ft AGL, descending toward airport
finalAligned with runway, < 1000ft AGL
landing_rollJust touched down, decelerating
taxi_inOn ground, moving after landing

Example: Landing Tracker

Here's a complete example that displays landing statistics:

html
<div id="landing-stats">
  <h3>Last Landing</h3>
  <div id="landing-rate">--</div>
  <div id="landing-quality">--</div>
  <div id="bounce-count">--</div>
</div>

<script type="module">
import GameGlue from 'gameglue';

const client = new GameGlue({
  clientId: 'your-client-id',
  redirect_uri: window.location.origin
});

await client.auth();

const listener = await client.createListener({
  userId: client.getUserId(),
  gameId: 'msfs'
});

listener.on('landing', (evt) => {
  document.getElementById('landing-rate').textContent =
    `${Math.abs(evt.landing_rate).toFixed(0)} fpm`;

  document.getElementById('landing-quality').textContent =
    evt.quality.toUpperCase();

  document.getElementById('bounce-count').textContent =
    evt.bounce_count === 0 ? 'No bounces' : `${evt.bounce_count} bounce(s)`;
});
</script>

Example: Flight Phase Display

Track the current phase and show phase history:

javascript
const phaseHistory = [];

listener.on('flight_phase', (evt) => {
  phaseHistory.push({
    phase: evt.phase,
    altitude: evt.altitude_msl,
    time: new Date(evt.timestamp)
  });

  updatePhaseDisplay(evt.phase);
  updatePhaseTimeline(phaseHistory);
});

TypeScript Types

If you're using TypeScript, the SDK provides types for all key events:

typescript
import type {
  LandingEvent,
  TakeoffEvent,
  FlightPhaseEvent,
  FlightPhase,
  LandingQuality
} from 'gameglue';

listener.on('landing', (evt: LandingEvent) => {
  const quality: LandingQuality = evt.quality;
  // ...
});

listener.on('flight_phase', (evt: FlightPhaseEvent) => {
  const phase: FlightPhase = evt.phase;
  // ...
});

Troubleshooting

Not receiving key events?

  • Key events require gg-client version 1.2.0 or later
  • Make sure the simulator is running and broadcasting telemetry
  • Check that regular update events are working first

Landing event not firing?

  • The aircraft must actually touch down (on_ground changes from false to true)
  • There's a 3-second stabilization period before the final landing event fires
  • Landings < 600 fpm with quality "crash" still fire an event

Flight phase seems stuck?

  • Phase detection uses altitude, speed, and ground state
  • Some transitions require specific conditions (e.g., taxi requires ground movement)
  • Paused simulation may not trigger phase changes