simconnect-go

module
v0.0.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 11, 2026 License: MIT

README

simconnect-go

Go bindings for the Microsoft Flight Simulator 2024 SimConnect SDK.

simconnect-go is a CGo-free, pure-syscall wrapper over SimConnect.dll, plus an idiomatic high-level client with context cancellation, typed SimVar definitions via reflection, channel-based request/response correlation, and per-domain facets (AI, camera, events, simvars, facilities, flights, input, system, …).

import simconnect "github.com/Zwergpro/simconnect-go/pkg/simconnect/client"

Features

  • No CGo, no C toolchain. SimConnect.dll is embedded into the binary and loaded at runtime via syscall.NewLazyDLLgo build produces a self-contained .exe that works on any Windows host. Override with simconnect.WithDLLPath(...) or the SIMCONNECT_DLL env var; missing override paths fall back to the embedded copy.
  • Two layers, your choice. Use the raw pkg/bindings shim (one Go function per native API, names mirror the SDK verbatim) or the high-level pkg/simconnect client.
  • Typed SimVar definitions. Tag a Go struct with sim:"NAME,units" and simvar.Define[T]() reflects it into a SimConnect data definition.
  • Context-cancellable session. simconnect.Open(ctx, ...) runs a background dispatch goroutine; Close is idempotent and fans ErrClosed to outstanding waiters.
  • Domain facets. sim.AI(), sim.Camera(), sim.Events(), sim.Simvar(), sim.System(), sim.Facilities(), sim.Flight(), sim.Input(), sim.Comm(), sim.Debug() — each lazily constructed and cached on the parent client.
  • Three dispatch patterns. One-shot waiters (simvar.GetOnce, system.RequestState), recurring subscriptions (SIMCONNECT_PERIOD_SIM_FRAME), and type-keyed listeners (RECV_ID_QUIT, RECV_ID_EXCEPTION, …).

Requirements

  • Windows host with Microsoft Flight Simulator 2024 running for runtime exercise.
  • No separate DLL deployment needed — the MSFS 2024 SimConnect redistributable is embedded. Use simconnect.WithDLLPath(path) or SIMCONNECT_DLL=path to load a different DLL (newer SDK, system-managed install). If the override path doesn't exist, the loader falls back to the embedded copy and logs one notice.
  • Go 1.26+.

The whole pkg/ tree carries //go:build windows. Tests cross-compile and run on any host.

Install

go get github.com/Zwergpro/simconnect-go

Quick start

This is cmd/monitor/main.go — the canonical "open → define → request → close" recipe. It prints user-aircraft position every 10 seconds.

//go:build windows

package main

import (
    "context"
    "errors"
    "fmt"
    "log"
    "os"
    "os/signal"
    "syscall"
    "time"

    simconnect "github.com/Zwergpro/simconnect-go/pkg/simconnect/client"
    "github.com/Zwergpro/simconnect-go/pkg/simconnect/core"
    "github.com/Zwergpro/simconnect-go/pkg/simconnect/simvar"
)

type aircraftPosition struct {
    Latitude  float64 `sim:"PLANE LATITUDE,degrees"`
    Longitude float64 `sim:"PLANE LONGITUDE,degrees"`
    Altitude  float64 `sim:"PLANE ALTITUDE,feet"`
}

func main() {
    ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
    defer stop()

    sim, err := simconnect.Open(ctx, "simconnect-go monitor",
        simconnect.WithPollInterval(5*time.Second))
    if err != nil {
        log.Fatalf("connect to MSFS 2024 SimConnect: %v", err)
    }
    defer sim.Close()

    go func() {
        for err := range sim.Errors() {
            log.Printf("simconnect error: %v", err)
        }
    }()

    positionDef, err := simvar.Define[aircraftPosition]()
    if err != nil {
        log.Fatalf("define aircraft position data: %v", err)
    }

    ticker := time.NewTicker(10 * time.Second)
    defer ticker.Stop()
    for {
        select {
        case <-ctx.Done():
            return
        case <-ticker.C:
            reqCtx, cancel := context.WithTimeout(ctx, 10*time.Second)
            pos, err := simvar.GetOnce(reqCtx, sim, positionDef, core.UserAircraft)
            cancel()
            if err != nil {
                if !errors.Is(err, context.Canceled) {
                    log.Printf("request: %v", err)
                }
                continue
            }
            fmt.Printf("lat=%.6f lon=%.6f alt=%.1f ft\n",
                pos.Latitude, pos.Longitude, pos.Altitude)
        }
    }
}
sim:"…" tag format

simvar.Define[T]() walks exported fields of T and reads sim:"NAME,units":

  • NAME — the SimVar name (PLANE LATITUDE, INDICATED ALTITUDE, …) verbatim from the MSFS SDK SimVar list.
  • units — measurement units exactly as the SDK expects (degrees, feet, knots, radians, bool, …).

bool fields are encoded as SimConnect INT32. For shapes reflection can't express (fixed-width strings, unexported fields), use simvar.DefineFields[T](fields ...Field).

Architecture

Two layers stacked on the SDK:

  • pkg/bindings/ — raw, hand-written syscall shim over SimConnect.dll. One Go function per native API, names mirror the SDK verbatim. No CGo, no .lib linkage.
  • pkg/simconnect/ — idiomatic Go API on top: context-cancellable session, ID allocators, channel-based request/response correlation, reflection-based SimVar definitions, per-domain facets.

For the full architectural tour with end-to-end traces, read docs/OVERVIEW.md.

Facet → SDK family
Facet Surface
ai Spawn ATC / non-ATC / parked / simulated objects; release control; remove; upload flight plans.
camera Acquire / release; set & get camera; enumerate definitions; status and world-locker subscriptions.
comm CommBus subscribe / call (inter-client and panel-to-app messaging).
debug LastSentPacketID, RequestResponseTimes for diagnosing timing.
events Client events, notification groups, client-data areas, flow events.
facilities Airport / waypoint / NDB / VOR list and detail queries with paginated aggregation.
flight Flight file save / load; flight-plan load.
input Input event enumeration, get / set / subscribe (hash-keyed dispatch).
simvar Typed SimVar definitions, one-shot reads, writes, and subscriptions.
system System state queries, ExecuteAction, system-event subscription, notification-group management.

Examples

Each subdirectory under cmd/ demonstrates one facet end-to-end.

Example Demonstrates
cmd/monitor Simplest example — prints user aircraft position every 10 s. Start here.
cmd/stats Continuous airspeed / altitude / telemetry monitor.
cmd/aiobject Spawning AI ATC and parked aircraft.
cmd/camera Camera acquire / set / get and definition enumeration.
cmd/communication CommBus subscribe and call round-trip.
cmd/debug LastSentPacketID and RequestResponseTimes.
cmd/eventsdata Custom data structs, mapping events, streaming SimObject data.
cmd/facilities Airport / waypoint / NDB / VOR list queries with pagination.
cmd/flights Flight-file load / save with metadata.
cmd/general Comprehensive system-state, system-event, action, notification-group walkthrough.
cmd/inputevents Enumerate input events, subscribe, get / set parameters.

Build

The whole pkg/ tree is //go:build windows. On a non-Windows host, always cross-compile:

GOOS=windows GOARCH=amd64 go build ./pkg/...
GOOS=windows GOARCH=amd64 go vet  ./pkg/...
GOOS=windows GOARCH=amd64 go test ./...

A bare go build ./... on Linux/macOS silently produces nothing because the build tag excludes every file in the package. Use the GOOS=windows form to actually exercise the code.

Build an example:

GOOS=windows GOARCH=amd64 go build -o monitor.exe ./cmd/monitor

The resulting .exe is self-contained: SimConnect.dll is embedded and extracted to %TEMP%\simconnect-go-<hash>.dll on first use. To load a different DLL, pass simconnect.WithDLLPath("C:\\path\\to\\SimConnect.dll") to Open or set SIMCONNECT_DLL in the environment; missing paths fall back to the embedded copy. Runtime exercise also needs MSFS 2024 actually running.

Gotchas

  • Field order in SIMCONNECT_* structs is load-bearing. They're overlaid on raw memory the DLL hands back. Don't reorder fields or insert padding. pkg/bindings/layout_test.go catches breakage.
  • Use packed accessors. SIMCONNECT_PACKED_FLOAT64, SIMCONNECT_PACKED_UINT64, SIMCONNECT_PACKED_DATA_LATLONALT, SIMCONNECT_PACKED_DATA_XYZ need their .Float64() / .SetFloat64() methods — reading the underlying bytes directly is a portability hazard.
  • Dispatch handlers must not block. They run inline on the polling goroutine. Long work belongs on a worker goroutine fed by a buffered channel.
  • Protocol values live in core, not client. core.UserAircraft, core.PeriodSecond, core.ExceptionError, every RecvID*/Period*/*Flag/Exception* constant, and the Message interface itself are in pkg/simconnect/core. client exports only the session.
  • Names mirror the SDK verbatim. SIMCONNECT_RECV_EVENT_FRAME, SIMCONNECT_PERIOD_SIM_FRAME, etc. — the official MSFS SDK docs are the only meaningful semantic reference.

Documentation

  • docs/OVERVIEW.md — full architectural tour, end-to-end traces, dispatch pump diagram, SDK surface map.
  • sdk/apidocs/ — vendored upstream MSFS SDK API documentation.

Status

This library is under active development against the MSFS 2024 SimConnect SDK. The bindings cover the full ~120-function native surface; the high-level client lifts the most common workflows. Issues and PRs are welcome.

License

See LICENSE for details.

Directories

Path Synopsis
cmd
aiobject command
camera command
communication command
debug command
eventsdata command
facilities command
flights command
general command
inputevents command
monitor command
stats command
pkg
bindings
Package bindings provides Go bindings for the Microsoft Flight Simulator SimConnect SDK (SimConnect.dll).
Package bindings provides Go bindings for the Microsoft Flight Simulator SimConnect SDK (SimConnect.dll).
simconnect/ai
Package ai implements the AI_Object SimConnect API category.
Package ai implements the AI_Object SimConnect API category.
simconnect/camera
Package camera implements the Camera SimConnect API category.
Package camera implements the Camera SimConnect API category.
simconnect/client
Package client provides the core SimConnect session, message dispatch, and ID allocation shared by all domain packages.
Package client provides the core SimConnect session, message dispatch, and ID allocation shared by all domain packages.
simconnect/comm
Package comm implements the Communication SimConnect API category (CommBus).
Package comm implements the Communication SimConnect API category (CommBus).
simconnect/core
Package core contains the shared protocol types, errors, and message definitions used by both the client session package and all domain facets.
Package core contains the shared protocol types, errors, and message definitions used by both the client session package and all domain facets.
simconnect/debug
Package debug implements the Debug SimConnect API category.
Package debug implements the Debug SimConnect API category.
simconnect/events
Package events contains client event, client data, and flow-event APIs.
Package events contains client event, client data, and flow-event APIs.
simconnect/eventsdata
Package eventsdata implements the Events_And_Data SimConnect API category.
Package eventsdata implements the Events_And_Data SimConnect API category.
simconnect/facilities
Package facilities implements the Facilities SimConnect API category.
Package facilities implements the Facilities SimConnect API category.
simconnect/flight
Package flight implements the Flights SimConnect API category: flight file save / load and flight-plan load.
Package flight implements the Flights SimConnect API category: flight file save / load and flight-plan load.
simconnect/general
Package general implements the General SimConnect API category.
Package general implements the General SimConnect API category.
simconnect/input
Package input implements the InputEvents SimConnect API category.
Package input implements the InputEvents SimConnect API category.
simconnect/simvar
Package simvar contains the typed SimVar definition and data request API.
Package simvar contains the typed SimVar definition and data request API.
simconnect/system
Package system contains SimConnect system state, system event, and action APIs.
Package system contains SimConnect system state, system event, and action APIs.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL