How GameGlue Works
This page explains the architecture of GameGlue and how the different pieces fit together. Understanding this will help you build better applications and troubleshoot issues.
The Big Picture
GameGlue connects games running on a user's PC to web applications running anywhere. Here's how data flows:
Game (MSFS) → Desktop Client → GameGlue Cloud → Your Web App
↑ ↓
← ← ← ← ← Commands ← ← ← ← ← ← ←- The game produces telemetry data (altitude, speed, position, etc.)
- The Desktop Client reads this data and sends it to the cloud
- GameGlue Cloud routes data to authenticated listeners
- Your app receives real-time updates via WebSocket
Commands flow in reverse: your app sends commands to the cloud, which forwards them to the Desktop Client, which executes them in the game.
Components
Desktop Client
The Desktop Client is a small application that runs alongside the game. It:
- Connects to the game using native protocols (SimConnect for MSFS)
- Reads telemetry data at high frequency
- Sends data to GameGlue Cloud
- Receives and executes commands from the cloud
Users must have the Desktop Client running for your app to work. If it's not running, your app won't receive any data.
GameGlue Cloud
The cloud service handles:
- Authentication - OAuth 2.0 login, session management, and permissions
- Routing - Directing data from the right game to the right listeners
- Filtering - Only sending the fields each listener has subscribed to
- Commands - Validating and forwarding commands to the Desktop Client
The cloud acts as a secure relay. Your app never connects directly to the user's PC.
SDK (GameGlueJS)
The JavaScript SDK provides a simple API for your web app:
- Handles OAuth authentication flow
- Manages WebSocket connections
- Provides event-based data updates
- Sends commands with result handling
The SDK abstracts away the complexity of authentication, WebSocket management, and data formatting.
Data Flow in Detail
Reading Telemetry
When you create a listener, here's what happens:
- Your app calls
createListener({ gameId: 'msfs', fields: [...] }) - The SDK opens a WebSocket to GameGlue Cloud
- The cloud checks authentication and permissions
- The cloud starts forwarding data from the user's Desktop Client
- Your app receives
updateevents with the requested fields
Data arrives at approximately the rate the game produces it (typically 20-60 updates per second for MSFS).
Subscribing to Fields
When you subscribe to specific fields:
javascript
const listener = await ggClient.createListener({
userId: userId,
gameId: 'msfs',
fields: ['indicated_altitude', 'ground_speed']
});The cloud only sends those two fields. This reduces bandwidth and processing.
You can change subscriptions at runtime without reconnecting:
javascript
await listener.subscribe(['fuel_quantity_gallons']);
await listener.unsubscribe(['ground_speed']);Sending Commands
When you send a command:
- Your app calls
listener.sendCommand('AUTOPILOT_ON', true) - The SDK sends the command to GameGlue Cloud
- The cloud validates permissions (
msfs:writescope required) - The cloud forwards the command to the Desktop Client
- The Desktop Client executes the command via SimConnect
- The SDK returns a result (success or failure)
Commands are validated at multiple levels:
- The cloud checks that your app has the appropriate write scope (e.g.,
msfs:write) - The Desktop Client checks that the command is valid for the current game state
Why This Architecture?
Security: Your app never connects directly to the user's PC. All communication goes through authenticated cloud services.
Cross-device: The web app can run on any device - phone, tablet, second monitor - not just the PC running the game.
Simplicity: You write JavaScript, not C++ or Rust. No need to understand SimConnect or other native APIs.
Scalability: Multiple apps can listen to the same game session. Each gets only the data it subscribes to.
Offline Behavior
GameGlue requires an internet connection. If the connection drops:
- Your listener will emit a
disconnectevent - Data stops flowing
- When reconnected, you'll need to create a new listener
Handle disconnections gracefully in your app:
javascript
listener.on('disconnect', () => {
showMessage('Connection lost. Reconnecting...');
// Attempt to reconnect
});