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
| Event | Description |
|---|---|
landing | Aircraft touchdown with quality rating and bounce tracking |
takeoff | Aircraft liftoff with rotation speed and configuration |
flight_phase | Phase 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
| Field | Type | Description |
|---|---|---|
landing_rate | number | Vertical speed at touchdown (fpm, negative = descending) |
quality | string | Quality rating based on landing rate |
bounce_count | number | Number of bounces (0 = smooth touchdown) |
bounces | array | Details of each bounce |
pitch | number | Pitch angle at touchdown (degrees) |
roll | number | Roll angle at touchdown (degrees) |
heading | number | Heading at touchdown (degrees) |
speed | number | Ground speed at touchdown (knots) |
latitude | number | Touchdown position |
longitude | number | Touchdown position |
timestamp | number | Unix timestamp (ms) |
Landing Quality Ratings
| Quality | Vertical Speed |
|---|---|
butter | < 60 fpm |
smooth | 60-120 fpm |
normal | 120-180 fpm |
firm | 180-300 fpm |
hard | 300-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
| Field | Type | Description |
|---|---|---|
rotation_speed | number | Indicated airspeed at liftoff (knots) |
pitch_at_liftoff | number | Pitch angle at liftoff (degrees) |
heading | number | Heading at liftoff (degrees) |
flaps_setting | number | Flap position (0-1) |
latitude | number | Liftoff position |
longitude | number | Liftoff position |
timestamp | number | Unix 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
| Field | Type | Description |
|---|---|---|
phase | string | Current flight phase |
previous_phase | string | Previous flight phase |
altitude_agl | number | Altitude above ground level (feet) |
altitude_msl | number | Altitude above mean sea level (feet) |
speed | number | Ground speed (knots) |
timestamp | number | Unix timestamp (ms) |
Available Phases
The flight phases follow a typical flight progression:
| Phase | Description |
|---|---|
parked | On ground, engines off or idle, no movement |
taxi_out | On ground, moving toward runway |
takeoff_roll | On runway, accelerating |
initial_climb | Just lifted off, < 1000ft AGL |
climb | Climbing, altitude increasing |
cruise | Level flight at altitude |
descent | Descending, altitude decreasing |
approach | < 3000ft AGL, descending toward airport |
final | Aligned with runway, < 1000ft AGL |
landing_roll | Just touched down, decelerating |
taxi_in | On 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
updateevents 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