Interface control document
1. Identification
| Item | Value |
|---|---|
| Document | ICD-CMSIMCONNECT-001 rev 1 |
| Product | SimConnect module (SimConnect Module in the module registry) |
| Product versions covered | 69d794b |
| Peer | Microsoft Flight Simulator 2024 or Lockheed Martin Prepar3D v6, through that simulator’s SimConnect server |
| Host | HEAT Capture, HEAT.Capture.ModuleSDK 2.0.5 |
| Data model | SimulationFrame carrying one EntityState for the user aircraft, plus transition events |
| Date | 2026-09-02 |
| Owner | VRAI Simulation |
2. Scope
This document defines the SimConnect data-definition and subscription contract the module establishes with the simulator, how the two simulator variants are selected and what differs between them, the connection and reconnect lifecycle, and the complete mapping from each registered simulation variable to the field it is published into.
The module is read-only with respect to simulator state. It registers data definitions, subscribes to data and to two system events, and writes nothing back into the simulator. The only file it writes is the remote connection configuration described in section 7.
Section 9 is the normative mapping. Section 10 lists the places in this revision where the value
written into a field does not match that field’s defined quantity, scale or unit. Both sections are
statements about revision 69d794b, not about the SimConnect API.
3. Interface inventory
| ID | Name | Direction | Transport | Peer |
|---|---|---|---|---|
| IF-CMSIMCONNECT-01 | Simulation variable subscription | Simulator to module | SimConnect client library, local IPC or IPv4 | MSFS or Prepar3D |
| IF-CMSIMCONNECT-02 | System event subscription | Simulator to module | Same SimConnect connection | MSFS or Prepar3D |
| IF-CMSIMCONNECT-03 | Remote connection configuration file | Module to filesystem | SimConnect.cfg beside the module binaries | SimConnect client library |
| IF-CMSIMCONNECT-04 | Frame publication | Module to host | Module SDK publication path | HEAT Capture |
4. Simulator variant selection
There is no runtime simulator detection and no setting that chooses a simulator. The variant is fixed by which of the two packages is installed. Each package ships a different module assembly that supplies its own backend, its own vendor wrapper and its own native client directory.
| Property | MSFS variant | Prepar3D variant |
|---|---|---|
| Module class | MsfsModule | Prepar3DModule |
| Settings id | SimConnectMsfs | SimConnectPrepar3D |
| Configuration section | HEAT.SimConnect.Msfs | HEAT.SimConnect.Prepar3D |
| Settings type | MsfsSettings, no members of its own | Prepar3DSettings, no members of its own |
| Backend | MsfsBackend | P3DBackend |
| Managed wrapper | Microsoft.FlightSimulator.SimConnect | LockheedMartin.Prepar3D.SimConnect |
| Native client directory | simconnect/msfs/SimConnect.dll, resolved relative to the module assembly | simconnect/p3d/SimConnect.dll, resolved relative to the module assembly |
| Application name sent on open | HEAT SimConnect (MSFS) | HEAT SimConnect (Prepar3D) |
| Pump thread name | SimConnect-MSFS-Pump | SimConnect-P3D-Pump |
| Extra data sources | none | WeaponsDataSource, DisplayProbeDataSource |
Everything else is shared. Both variants register the same ten built-in definition groups, request them at the same periods, and run the same mapper and the same event detector. The only capture differences are the two Prepar3D data sources in sections 9.11 and 9.12.
Both variants are registered as ModuleType.System with ModuleStartupType.SystemStartup, so they
connect and hold a connection from HEAT Capture startup, independently of whether a capture session
is running.
5. IF-CMSIMCONNECT-01 Simulation variable subscription
5.1 Transport and addressing
| Item | Value |
|---|---|
| Client library | The simulator’s own managed SimConnect wrapper over its native SimConnect.dll |
| Native resolution | The backend adds its simconnect/<variant>/ directory to the process DLL search path through SetDefaultDllDirectories, AddDllDirectory and SetDllDirectory before the mixed-mode wrapper type is touched |
| Local addressing | Config index 0, which uses the SimConnect client library’s own default local endpoint. The module supplies no local address, pipe name or port |
| Remote addressing | Config index 1, resolved from the SimConnect.cfg written by IF-CMSIMCONNECT-03: IPv4, RemoteHost, RemotePort |
| Simulation object | SIMCONNECT_OBJECT_ID_USER for every request. No AI or multiplayer object is requested |
| Message pump | One background thread per connection, waiting on an auto-reset EventWaitHandle with a 500 ms timeout and calling ReceiveMessage when signalled |
5.2 Connection lifecycle and reconnect
InitialiseModule creates the client, subscribes to its disconnect and active-state events, makes
one synchronous connect attempt, and starts the silence timer. This runs inside the SDK
StartupTimeout, 5 seconds by default.
On the simulator’s open acknowledgement the backend raises Opened on the pump thread, and the
client then, in this order: registers the ten built-in definition groups, starts the ten data
requests, subscribes to the Sim and Pause system events, registers each simulator-specific data
source, and logs SimConnect connected to {App} (SimConnect {Major}.{Minor}) with the application
name and SimConnect version the simulator reported.
StartCapture resets the event detector and sets the simulation tick counter to zero. It does not
touch the connection or the cache. EndCapture does nothing.
Reconnect is driven from two triggers. A failed connect attempt logs
SimConnect connection attempt failed - will retry as a warning and starts the reconnect loop. A
disconnect, meaning either the simulator’s quit message or an exception on the pump thread, starts
the same loop.
The loop waits ReconnectIntervalMs, default 5000 ms, disposes the current backend, and connects
again. A failure logs SimConnect reconnect attempt failed at debug level and doubles the delay,
capped at 30000 ms. A success logs SimConnect reconnected and ends the loop. The loop is
unbounded in attempts and only ends on success, on cancellation, or on module disposal. The
backoff is not reset by a later success, because each new loop starts from ReconnectIntervalMs.
Because the backend is recreated on every attempt, the definition groups, data requests, system event subscriptions and data sources are all re-registered on each successful reconnect, and the snapshot cache from before the disconnect is retained rather than cleared.
Disposal cancels the reconnect loop, disposes the silence timer, and disposes the client. Backend disposal cancels the pump, joins the pump thread with a 2 second timeout so the native handle is not freed while a dispatch is in progress, then disposes the wrapper and swallows any exception from it.
5.3 Authentication
None, in either mode. Local mode inherits whatever access control the simulator’s own SimConnect
endpoint applies to local clients. Remote mode is a plain IPv4 connection to RemoteHost on
RemotePort; the generated configuration carries no credential, and the module presents none.
5.4 Wire format
Each definition group is a SimConnect data definition built by adding its variables one at a time, then binding a sequentially laid-out managed struct to the group. Struct packing is 1, character set is ANSI, and the field order in the struct must equal the order the variables were added. Meaning is therefore entirely positional: nothing in the payload identifies which variable a field came from.
| Group | Struct | Variables | Requested period |
|---|---|---|---|
Core | CoreData | 31 | Visual frame |
Engine | EngineData | 5 | Visual frame |
FWA | FWAData | 27 | Visual frame |
RWA | RWAData | 4 | Visual frame |
LandingGear | LandingGearData | 5 | Visual frame |
AircraftInfo | AircraftInfoData | 2 | Second |
Avionics | AvionicsData | 17 | Visual frame |
PropulsionControl | PropulsionControlData | 6 | Visual frame |
FuelSystem | FuelSystemData | 22 | Visual frame |
ATC | ATCData | 7 | Second |
Simulator-specific sources use request and definition identifiers at or above 100 so they cannot collide with the built-in groups. The Prepar3D weapons group uses 100 and the Prepar3D display probe uses 120.
Requested units are expressed through a fixed neutral enumeration, and each value maps to exactly one SimConnect unit string:
| Neutral unit | SimConnect unit string |
|---|---|
None | null, no units string sent |
Boolean | Bool |
Number | number |
Degrees | degrees |
Feet | feet |
FeetPerMinute | feet per minute |
FeetPerSecond | feet per second |
FeetPerSecondSquared | feet per second squared |
Knots | knots |
Gallons | gallons |
Pounds | pounds |
FootPounds | foot pounds |
Percent | percent |
PercentOver100 | percent over 100 |
Celsius | celsius |
Millibars | millibars |
SlugsPerCubicFoot | slugs per cubic foot |
Mach | mach |
GForce | GForce |
Meters | meters |
Data types are FLOAT64, INT32, STRING32 and STRING256. String variables are registered with
the None unit, because SimConnect rejects a non-null units string on a string type.
Every arriving payload is boxed by the backend and stored, under a lock, into a per-group slot in the client’s snapshot cache. Each new payload replaces the previous one for that group; no history is kept.
5.5 Delivery cadence
Delivery is simulator-driven. Eight groups are requested per visual frame, so their arrival rate is
the simulator’s render rate. AircraftInfo and ATC are requested once per second. The Prepar3D
weapons group is per visual frame and the Prepar3D display probe is once per second.
Publication is not tied to delivery. The module reads the cache at the SDK Interval cadence,
1000 ms by default, so at a 60 Hz render rate roughly 59 of every 60 arrivals of a visual-frame
group are overwritten before they are ever read. This is by design for state, but it also means
transitions are detected only against the values latched at successive publication cycles, not
against every value the simulator delivered.
6. IF-CMSIMCONNECT-02 System event subscription
Two named SimConnect system events are subscribed on every connect: Sim and Pause. Their
payload is treated as a boolean, non-zero meaning true.
The module keeps both flags and derives one combined active state, defined as running and not paused. It raises a change only when that combined state flips.
| Combined state | Condition | Module action |
|---|---|---|
| Becomes active | Sim non-zero and Pause zero | If StartOnSimRunning is set and no session is started, logs Simulation is running - starting session and asks the host to start a session |
| Becomes inactive | Sim zero, or Pause non-zero | If StopOnSimPaused is set and a session is started, logs Simulation paused or stopped - stopping session and asks the host to stop the session |
The simulator’s quit message also clears both flags, without raising a combined-state change.
A separate silence timer runs on a 1 second period, independent of these events. When
StopOnSilence is set, a session is started, the client is connected, and the time since the last
payload of any kind is at least SilenceThreshold, it logs
{Time}s of silence detected - stopping session and asks the host to stop the session. The logged
value is the seconds component of SilenceThreshold, so a threshold expressed as a whole number of
minutes logs as 0s.
7. IF-CMSIMCONNECT-03 Remote connection configuration file
When RemoteHost is empty or null, no file is written and config index 0 is used. When
RemoteHost has a value, the module overwrites SimConnect.cfg in the application base directory,
beside the module binaries, with exactly this content and then connects with config index 1:
[SimConnect.1]
Protocol=IPv4
Address=<RemoteHost>
Port=<RemotePort>
MaxReceiveSize=4096The protocol, the section index and the 4096-byte receive size are fixed in code. The file is rewritten on every connect attempt, including every reconnect attempt, and is never deleted.
8. IF-CMSIMCONNECT-04 Frame publication and data model reference
8.1 Entity identity
| Item | Value |
|---|---|
| Entity name | The TITLE variable last received in the AircraftInfo group, or the literal Unknown Aircraft when no title has been cached |
| Entity id | 64-bit FNV-1a hash over the UTF-8 bytes of that same cached title, or 0 when the title is null or empty |
| Aircraft type | Derived from the CATEGORY variable: Helicopter gives rotary-wing; Airplane, Glider and Amphibian give fixed-wing; every other value, including an empty one, gives unknown |
The identity is derived from the cached title, not from the fallback name, so a frame published
before the first AircraftInfo payload is named Unknown Aircraft with id 0. The hash is
computed from scratch on every publication cycle and is stable across processes and sessions for a
given title.
8.2 Frame envelope
Each publication cycle produces one SimulationFrame with one EntityState.
| Field | Value |
|---|---|
SimulationFrame.simulation_tick | A counter incremented once per published frame, reset to zero by StartCapture |
SimulationFrame.capture_time | Never set by this module; left at the proto default |
SimulationFrame.simulation_time_seconds | Never set; left at the proto default |
SimulationFrame.entities | Exactly one EntityState |
EntityState.timestamp | Never set; left at the proto default |
| Event timestamps | Host wall clock, UTC Unix milliseconds, taken once per cycle and applied to every event in that frame |
The only timestamp a consumer can rely on for state is therefore the SDK’s own envelope value,
DataPacket.TimestampUnixMs, taken when the payload is wrapped. See
the Module SDK ICD for that envelope.
8.3 Publication preconditions
Nothing is published, and the cycle returns no frame, in either of these cases: the client is null
or reports not connected, or the Core group has never delivered a payload. The module does not
publish a seeded or zeroed frame.
Once the Core group has delivered once, a frame is published every cycle even if the connection
later drops mid-cycle, and every group other than Core is optional. An absent group means its
components are omitted, except where section 10 records a group whose absence produces a published
value rather than an omission.
Component presence is therefore:
| Component | Condition |
|---|---|
WorldPositionComponent, DynamicsComponent, AirDataComponent, CloudDataComponent, GenericAircraftComponent | Always, since Core is a precondition |
AircraftEngineComponent | Engine cached |
AircraftAvionicsComponent | Avionics cached |
ResourceStoresComponent, FuelSystemComponent | FuelSystem cached |
AircraftLandingGearComponent | LandingGear cached |
FWAControlSurfacesComponent, FWAInputComponent, FWADataComponent | Aircraft type is fixed-wing and FWA cached |
RotaryWingDataComponent | Aircraft type is rotary-wing and RWA cached |
ATCDataComponent | ATC cached |
AircraftDisplayStateComponent | Prepar3D variant only, and the display probe has delivered once |
An unknown aircraft type publishes neither the fixed-wing nor the rotary-wing components, and is not logged.
8.4 Events
Events are edge-triggered against the previous publication cycle’s value. Detector state is
recreated by StartCapture, with initial values of not stalling, not overspeeding, on the ground,
and engine not running.
| Event | Payload | Trigger | Condition |
|---|---|---|---|
StateChangedEvent | state is stall_warning_on | STALL WARNING false to true | Fixed-wing only |
StateChangedEvent | state is stall_warning_off | STALL WARNING true to false | Fixed-wing only |
StateChangedEvent | state is overspeed_warning_on | OVERSPEED WARNING false to true | Fixed-wing only |
StateChangedEvent | state is grounded | SIM ON GROUND false to true | Any type |
StateChangedEvent | state is airborne | SIM ON GROUND true to false | Any type |
StateChangedEvent | state is engine_running | ENG COMBUSTION:1 false to true | Any type |
StateChangedEvent | state is engine_stopped | ENG COMBUSTION:1 true to false | Any type |
There is deliberately no overspeed_warning_off: the detector is given a null falling-edge label
for that transition, so a cleared overspeed warning produces no event.
Because the initial state assumes on the ground with the engine off, a session started with the
aircraft already airborne or already running publishes airborne or engine_running on the first
cycle even though nothing changed at that instant.
The detector also contains a threshold-event helper that nothing calls, so no ThresholdEvent is
ever published by this module. G-force is captured and published as state only.
Prepar3D adds the discrete combat events in section 9.11, drained once per cycle from the weapons source. They carry the same entity id and timestamp as the frame’s other events, not the time the transition was observed on the pump thread.
9. Simulation variable to published field mapping
Conversion factors used below, as defined in the mapper:
| Conversion | Factor |
|---|---|
| Feet to metres, and feet per second to metres per second, and feet per second squared to metres per second squared | 0.3048 |
| Knots to metres per second | 0.51444 |
| Pounds-force to newtons | 4.44822 |
| Foot-pounds to newton-metres | 1.3558179483314004 |
Every value is narrowed from the transported double to float when written. “Not published” means
the variable is registered and cached but no published field is derived from it.
9.1 Core group
Present in every published frame.
| Simulation variable | Requested unit | Published field | Conversion |
|---|---|---|---|
PLANE LATITUDE | degrees | WorldPositionComponent.latitude | none |
PLANE LONGITUDE | degrees | WorldPositionComponent.longitude | none |
PLANE ALTITUDE | feet | WorldPositionComponent.altitude and GenericAircraftComponent.true_altitude | feet to metres |
PLANE HEADING DEGREES TRUE | degrees | WorldPositionComponent.heading | none |
PLANE PITCH DEGREES | degrees | WorldPositionComponent.pitch_deg | none |
PLANE BANK DEGREES | degrees | WorldPositionComponent.roll_deg | none |
VELOCITY WORLD X | feet per second | DynamicsComponent.velocity.x | feet to metres |
VELOCITY WORLD Y | feet per second | DynamicsComponent.velocity.y | feet to metres |
VELOCITY WORLD Z | feet per second | DynamicsComponent.velocity.z | feet to metres |
ACCELERATION WORLD X | feet per second squared | DynamicsComponent.acceleration.x | feet to metres |
ACCELERATION WORLD Y | feet per second squared | DynamicsComponent.acceleration.y | feet to metres |
ACCELERATION WORLD Z | feet per second squared | DynamicsComponent.acceleration.z | feet to metres |
GROUND VELOCITY | knots | DynamicsComponent.ground_speed | knots to metres per second |
VELOCITY BODY Z | feet per second | DynamicsComponent.magnitude | feet to metres |
SIM ON GROUND | Bool | DynamicsComponent.is_grounded | non-zero test |
AMBIENT TEMPERATURE | celsius | AirDataComponent.ambient_air_temperature | none |
TOTAL AIR TEMPERATURE | celsius | AirDataComponent.total_air_temperature | none |
AMBIENT PRESSURE | millibars | AirDataComponent.air_pressure | none |
BAROMETER PRESSURE | millibars | AirDataComponent.sea_level_pressure | none |
AMBIENT DENSITY | slugs per cubic foot | AirDataComponent.density | none |
AMBIENT WIND VELOCITY | knots | AirDataComponent.wind_velocity | knots to metres per second |
AMBIENT WIND DIRECTION | degrees | AirDataComponent.surface_wind_direction | none |
SPEED OF SOUND | knots | AirDataComponent.speed_of_sound | knots to metres per second |
AMBIENT VISIBILITY | meters | CloudDataComponent.visibility | none |
AMBIENT IN CLOUD | Bool | CloudDataComponent.in_cloud | non-zero test |
PLANE ALT ABOVE GROUND | feet | GenericAircraftComponent.agl | feet to metres |
INDICATED ALTITUDE | feet | not published, see SIM-01 in section 10 | not applicable |
KOHLSMAN SETTING MB | millibars | GenericAircraftComponent.barometric_altitude, see SIM-01 | none |
G FORCE | GForce | GenericAircraftComponent.g_force | none |
MAX G FORCE | GForce | GenericAircraftComponent.g_force_max | none |
MIN G FORCE | GForce | GenericAircraftComponent.g_force_min | none |
9.2 Engine group
| Simulation variable | Requested unit | Published field | Conversion |
|---|---|---|---|
ENG COMBUSTION:1 | Bool | AircraftEngineComponent.engine_state and AircraftEngineComponent.ignition, both from this one variable | non-zero test |
GENERAL ENG THROTTLE LEVER POSITION:1 | percent over 100 | AircraftEngineComponent.throttle | none |
TURB ENG JET THRUST:1 | pounds | AircraftEngineComponent.thrust | pounds-force to newtons |
TURB ENG THROTTLE LEVER POSITION:1 | percent over 100 | AircraftEngineComponent.thrust_percentage | none |
GENERAL ENG REVERSE THRUST ACTIVE:1 | Bool | AircraftEngineComponent.reverse_thrust_active | non-zero test |
Only engine 1 is registered. A multi-engine aircraft publishes one engine component describing its first engine.
9.3 Fixed-wing group
Published only when the aircraft type resolves to fixed-wing.
| Simulation variable | Requested unit | Published field | Conversion |
|---|---|---|---|
AILERON POSITION | percent over 100 | FWAControlSurfacesComponent.aileron_position | none |
ELEVATOR POSITION | percent over 100 | FWAControlSurfacesComponent.elevator_position | none |
RUDDER POSITION | percent over 100 | FWAControlSurfacesComponent.rudder_position | none |
AILERON TRIM PCT | percent over 100 | FWAControlSurfacesComponent.aileron_trim_percentage | none |
ELEVATOR TRIM PCT | percent over 100 | FWAControlSurfacesComponent.elevator_trim_percentage | none |
RUDDER TRIM PCT | percent over 100 | FWAControlSurfacesComponent.rudder_trim_percentage | none |
FLAPS HANDLE INDEX | number | FWAControlSurfacesComponent.flaps_position | none |
FLAPS HANDLE PERCENT | percent over 100 | FWAControlSurfacesComponent.flaps_position_percentage | none |
SPOILERS HANDLE POSITION | percent over 100 | FWAControlSurfacesComponent.spoilers_position | truncating cast to a 32-bit integer, see section 10 |
G FORCE (FWA copy) | GForce | not published; GenericAircraftComponent.g_force is taken from the Core copy instead | not applicable |
YOKE X POSITION | percent over 100 | FWAInputComponent.yoke_value.x | none |
YOKE Y POSITION | percent over 100 | FWAInputComponent.yoke_value.y | none |
RUDDER PEDAL POSITION | percent over 100 | FWAInputComponent.rudder_value | none |
BRAKE LEFT POSITION | percent over 100 | FWAInputComponent.toe_brakes_left | none |
BRAKE RIGHT POSITION | percent over 100 | FWAInputComponent.toe_brakes_right | none |
AIRSPEED INDICATED | knots | FWADataComponent.airspeed_calibrated, see section 10 | knots to metres per second |
AIRSPEED MACH | mach | FWADataComponent.airspeed_mach | none |
BARBER POLE SPEED | knots | FWADataComponent.airspeed_barber_pole | knots to metres per second |
STALL WARNING | Bool | FWADataComponent.stall_warning | non-zero test |
OVERSPEED WARNING | Bool | FWADataComponent.overspeed_warning | non-zero test |
ATTITUDE INDICATOR PITCH DEGREES | degrees | FWADataComponent.altitude_indicator_pitch_degrees | none |
ATTITUDE INDICATOR BANK DEGREES | degrees | FWADataComponent.altitude_indicator_bank_degrees | none |
PLANE HEADING DEGREES GYRO | degrees | FWADataComponent.plane_gyro_heading_degrees | none |
TURN COORDINATOR BALL | percent | FWADataComponent.turn_coordinator_ball | none |
ANGLE OF ATTACK INDICATOR | degrees | FWADataComponent.aoa_indicator | none |
RADIO HEIGHT | feet | FWADataComponent.radio_height | feet to metres |
GEAR WARNING | number | FWADataComponent.gear_warning_value | none |
FWADataComponent.indicated_altitude and FWADataComponent.kohlsman_setting exist in the schema
and are never populated by this module. That is the other half of SIM-01.
FWAInputComponent also carries five fields sourced from other groups:
| Field | Source | Value when the source group is not cached |
|---|---|---|
throttle_lever_position | PropulsionControl group, GENERAL ENG THROTTLE LEVER POSITION:1 | 0 |
commanded_throttle | PropulsionControl group, TURB ENG THROTTLE LEVER POSITION:1 | 0 |
autothrottle_active | Avionics group, AUTOTHROTTLE ACTIVE | true, see section 10 |
afterburner_active | PropulsionControl group, TURB ENG AFTERBURNER:1 | true, see section 10 |
reverse_thrust_active | PropulsionControl group, GENERAL ENG REVERSE THRUST ACTIVE:1 | true, see section 10 |
9.4 Rotary-wing group
Published only when the aircraft type resolves to rotary-wing.
| Simulation variable | Requested unit | Published field | Conversion |
|---|---|---|---|
ENG TORQUE:1 | foot pounds | RotaryWingDataComponent.main_rotors_torque, as the single element of the list | foot-pounds to newton-metres |
TAIL ROTOR BLADE PITCH PCT | percent over 100 | RotaryWingDataComponent.tail_rotor_torque, see section 10 | none |
ROTOR LATERAL TRIM PCT | percent over 100 | RotaryWingDataComponent.rotor_lateral_trim | none |
ROTOR LONGITUDINAL TRIM PCT | percent over 100 | RotaryWingDataComponent.rotor_longitudinal_trim | none |
engine_torque_limit is not populated.
9.5 Landing gear group
| Simulation variable | Requested unit | Published field | Conversion |
|---|---|---|---|
GEAR TOTAL PCT EXTENDED | percent over 100 | AircraftLandingGearComponent.extended_percentage, see section 10 | none |
GEAR HANDLE POSITION | Bool | AircraftLandingGearComponent.gear_handle_value | non-zero test |
BRAKE PARKING INDICATOR | Bool | AircraftLandingGearComponent.parking_brake_enabled | non-zero test |
IS GEAR RETRACTABLE | Bool | AircraftLandingGearComponent.is_gear_retractable | non-zero test |
GEAR EMERGENCY HANDLE POSITION | Bool | AircraftLandingGearComponent.gear_emergency_handle_position | non-zero test |
No WheelComponent is populated, and allow_steering, parking_brake_available,
gear_max_airspeed, hydraulic_pressure, lock_on and is_damaged are not set.
9.6 Aircraft identity group
| Simulation variable | Requested unit | Type | Use |
|---|---|---|---|
CATEGORY | null | STRING32 | Aircraft type classification described in 8.1. Not published as a field |
TITLE | null | STRING256 | Entity name and entity id described in 8.1 |
9.7 Avionics group
| Simulation variable | Requested unit | Published field | Conversion |
|---|---|---|---|
AUTOPILOT MASTER | Bool | AircraftAvionicsComponent.autopilot_master | non-zero test |
AUTOPILOT FLIGHT DIRECTOR ACTIVE | Bool | AircraftAvionicsComponent.flight_director_master | non-zero test |
AUTOTHROTTLE ACTIVE | Bool | AircraftAvionicsComponent.autothrottle_master, and FWAInputComponent.autothrottle_active on fixed-wing | non-zero test |
AUTOPILOT HEADING LOCK DIR | degrees | AircraftAvionicsComponent.selected_heading_degrees | none |
AUTOPILOT ALTITUDE LOCK VAR | feet | AircraftAvionicsComponent.selected_altitude_meters | feet to metres |
AUTOPILOT AIRSPEED HOLD VAR | knots | AircraftAvionicsComponent.selected_indicated_airspeed_meters_per_second | knots to metres per second |
AUTOPILOT MACH HOLD VAR | mach | AircraftAvionicsComponent.selected_mach | none |
AUTOPILOT VERTICAL HOLD VAR | feet per minute | AircraftAvionicsComponent.selected_vertical_speed_meters_per_second | feet to metres, then divided by 60 |
AUTOPILOT APPROACH HOLD | Bool | active_lateral_mode and active_lateral_mode_label, first priority | see mode resolution below |
AUTOPILOT NAV1 LOCK | Bool | active_lateral_mode and active_lateral_mode_label, second priority | see mode resolution below |
AUTOPILOT HEADING LOCK | Bool | active_lateral_mode and active_lateral_mode_label, third priority | see mode resolution below |
AUTOPILOT BACKCOURSE HOLD | Bool | active_lateral_mode_label only | see mode resolution below |
AUTOPILOT GLIDESLOPE HOLD | Bool | active_vertical_mode and active_vertical_mode_label, first priority | see mode resolution below |
AUTOPILOT VERTICAL HOLD | Bool | active_vertical_mode and active_vertical_mode_label, second priority | see mode resolution below |
AUTOPILOT ALTITUDE LOCK | Bool | active_vertical_mode and active_vertical_mode_label, third priority | see mode resolution below |
AUTOPILOT AIRSPEED HOLD | Bool | not published | not applicable |
AUTOPILOT MACH HOLD | Bool | not published | not applicable |
Mode resolution is strictly first-match in the priority order shown, so only one lateral and one vertical mode is ever reported even when the simulator has several engaged.
| Resolved mode | Enum value | Label |
|---|---|---|
| Lateral, approach hold engaged | AIRCRAFT_AUTOPILOT_LATERAL_MODE_APPROACH | approach |
| Lateral, nav1 lock engaged | AIRCRAFT_AUTOPILOT_LATERAL_MODE_NAV | nav |
| Lateral, heading lock engaged | AIRCRAFT_AUTOPILOT_LATERAL_MODE_HEADING_HOLD | heading_hold |
| Lateral, none engaged | AIRCRAFT_AUTOPILOT_LATERAL_MODE_UNSPECIFIED | empty string |
| Vertical, glideslope hold engaged | AIRCRAFT_AUTOPILOT_VERTICAL_MODE_GLIDESLOPE | glideslope |
| Vertical, vertical hold engaged | AIRCRAFT_AUTOPILOT_VERTICAL_MODE_VS | vertical_speed |
| Vertical, altitude lock engaged | AIRCRAFT_AUTOPILOT_VERTICAL_MODE_ALT_HOLD | altitude_hold |
| Vertical, none engaged | AIRCRAFT_AUTOPILOT_VERTICAL_MODE_UNSPECIFIED | empty string |
Backcourse hold is a label-only override: when it is engaged the label becomes backcourse
regardless of the other lateral variables, while active_lateral_mode still reports whichever of
approach, nav or heading hold matched. A consumer that reads the enum and the label together will
see them disagree in that case. There is no backcourse value in the lateral mode enumeration.
9.8 Propulsion control group
| Simulation variable | Requested unit | Published field |
|---|---|---|
GENERAL ENG THROTTLE LEVER POSITION:1 | percent over 100 | FWAInputComponent.throttle_lever_position, fixed-wing only |
TURB ENG THROTTLE LEVER POSITION:1 | percent over 100 | FWAInputComponent.commanded_throttle, fixed-wing only |
GENERAL ENG REVERSE THRUST ACTIVE:1 | Bool | FWAInputComponent.reverse_thrust_active, fixed-wing only |
TURB ENG AFTERBURNER:1 | Bool | FWAInputComponent.afterburner_active, fixed-wing only |
TURB ENG AFTERBURNER STAGE ACTIVE:1 | number | not published; module debug view only |
TURB ENG AFTERBURNER PCT ACTIVE:1 | percent over 100 | not published; module debug view only |
A rotary-wing or unknown-type aircraft publishes nothing at all from this group, because its only published destination is the fixed-wing input component.
9.9 Fuel system group
Nine ResourceStoreEntry rows are published unconditionally whenever the group is cached, whether
or not the aircraft has the corresponding tank. A tank the aircraft does not have reports quantity
0, which is indistinguishable from a real empty tank.
| Simulation variable pair | Requested units | store_id | store_label | location | jettisonable |
|---|---|---|---|---|---|
FUEL TANK LEFT MAIN QUANTITY and FUEL TANK LEFT MAIN LEVEL | gallons, percent over 100 | left_main | Left Main | STORE_LOCATION_INTERNAL | false |
FUEL TANK RIGHT MAIN QUANTITY and FUEL TANK RIGHT MAIN LEVEL | gallons, percent over 100 | right_main | Right Main | STORE_LOCATION_INTERNAL | false |
FUEL TANK CENTER QUANTITY and FUEL TANK CENTER LEVEL | gallons, percent over 100 | center | Center | STORE_LOCATION_INTERNAL | false |
FUEL TANK LEFT AUX QUANTITY and FUEL TANK LEFT AUX LEVEL | gallons, percent over 100 | left_aux | Left Aux | STORE_LOCATION_INTERNAL | false |
FUEL TANK RIGHT AUX QUANTITY and FUEL TANK RIGHT AUX LEVEL | gallons, percent over 100 | right_aux | Right Aux | STORE_LOCATION_INTERNAL | false |
FUEL TANK LEFT TIP QUANTITY and FUEL TANK LEFT TIP LEVEL | gallons, percent over 100 | left_tip | Left Tip | STORE_LOCATION_INTERNAL | false |
FUEL TANK RIGHT TIP QUANTITY and FUEL TANK RIGHT TIP LEVEL | gallons, percent over 100 | right_tip | Right Tip | STORE_LOCATION_INTERNAL | false |
FUEL TANK EXTERNAL1 QUANTITY and FUEL TANK EXTERNAL1 LEVEL | gallons, percent over 100 | external_1 | External 1 | STORE_LOCATION_EXTERNAL | true |
FUEL TANK EXTERNAL2 QUANTITY and FUEL TANK EXTERNAL2 LEVEL | gallons, percent over 100 | external_2 | External 2 | STORE_LOCATION_EXTERNAL | true |
Within each row, the quantity variable becomes current_quantity unconverted, and the level
variable is multiplied by 100 and carried as an extra_data entry keyed fill_level_percent. Every
row also sets resource_type to RESOURCE_TYPE_FUEL and unit to RESOURCE_UNIT_GALLONS, and
sets max_quantity to 0, resource_type_label to an empty string and unit_label to an empty
string.
The remaining variables in the group:
| Simulation variable | Requested unit | Published field |
|---|---|---|
FUEL DUMP ACTIVE | Bool | FuelSystemComponent.fuel_dump_active |
FUEL CROSS FEED | Bool | FuelSystemComponent.crossfeed_enabled |
FUEL TOTAL QUANTITY | gallons | not published; module debug view only |
FUEL TOTAL QUANTITY WEIGHT | pounds | not published; module debug view only |
9.10 ATC identity group
| Simulation variable | Requested unit | Type | Published field |
|---|---|---|---|
ATC TYPE | null | STRING256 | ATCDataComponent.atc_type |
ATC MODEL | null | STRING256 | ATCDataComponent.atc_model |
ATC ID | null | STRING256 | ATCDataComponent.atc_id |
ATC AIRLINE | null | STRING256 | ATCDataComponent.atc_airline |
ATC FLIGHT NUMBER | null | STRING32 | ATCDataComponent.atc_flight_number |
HSI STATION IDENT | null | STRING32 | ATCDataComponent.hsi_station_ident |
TRANSPONDER CODE:1 | number | INT32 | ATCDataComponent.transponder_code, formatted as four uppercase hexadecimal digits |
The transponder value is registered with the number unit but formatted on the assumption that the
simulator returned a binary-coded value, so that each hexadecimal digit is one squawk digit. The
module does not validate that assumption, and it does not reject a value whose hexadecimal
rendering contains digits 8 or above, which cannot occur in a real octal squawk. A code that
needs more than four hexadecimal digits is rendered at its natural width rather than truncated.
9.11 Prepar3D weapons group
Registered and requested per visual frame by the Prepar3D variant only. This group populates no component; it produces only discrete events. Per-station variables are registered for stations 1 to 16 and marshalled as fixed 16-element arrays; the simulator reports zero for stations beyond the aircraft’s actual station count.
| Simulation variable | Requested unit | Published result |
|---|---|---|
WEAPON SYSTEM STATION OBJECT COUNT:1..16 | number | A decrease on any station emits FiredEvent |
WEAPON SYSTEM STATION OBJECT ID:1..16 | number | FiredEvent.bullet_entity_id for that station’s release |
WEAPON TYPE | null, STRING256 | Both FiredEvent.weapon_name and FiredEvent.munition_name for a station release, and the suffix of the weapon_selected state |
GUN SYSTEM TRIGGER ENGAGED | Bool | A false-to-true edge emits FiredEvent with weapon_name gun and munition_name rounds |
COUNTERMEASURE SYSTEM STATION OBJECT COUNT:1..16 | number | A decrease on any station emits CountermeasureEvent with an empty countermeasure_name |
FCS TARGETED OBJECT ID | number | A change emits TargetTrackingEvent; see below |
WEAPON SYSTEM ARMED | Bool | A change emits StateChangedEvent with state master_arm_on or master_arm_off |
WEAPON SYSTEM TRIGGER ENGAGED | Bool | not published |
STATION COUNT | number | not published |
GUN SYSTEM STATION AMMO COUNT:1..16 | number | not published |
FCS TARGETED LATITUDE | degrees | not published |
FCS TARGETED LONGITUDE | degrees | not published |
FCS TARGETED ALTITUDE | feet | not published |
On a target change the source emits, in this order, a TargetTrackingEvent with state Released,
sensor_or_lock_type fcs and reason changed for the previous target when that was non-zero,
then a TargetTrackingEvent with state Locked and sensor_or_lock_type fcs for the new target
when that is non-zero. Target ids are read as unsigned 32-bit values before being widened, so a
negative identifier from the simulator becomes a large positive entity id.
A weapon-selection change emits StateChangedEvent with state set to weapon_selected: followed
by the reported weapon type. A selection clearing to an empty string emits nothing.
Transitions are detected on the pump thread at visual-frame rate and queued, then drained once per publication cycle, so this source does not lose transitions between cycles the way the shared detector does. The queue is unbounded.
The first payload after each connect establishes the baseline and emits nothing.
9.12 Prepar3D display probe group
Registered and requested once per second by the Prepar3D variant only. All eight variables are
carried verbatim as AircraftDisplayStateComponent.extra_data entries, and the first four also feed
the derived page labels.
| Simulation variable | Requested unit | extra_data key |
|---|---|---|
AVIONICS MASTER SWITCH | Bool | avionics_master_switch |
CIRCUIT GENERAL PANEL ON | Bool | circuit_general_panel_on |
CIRCUIT AVIONICS ON | Bool | circuit_avionics_on |
CIRCUIT AUTOPILOT ON | Bool | circuit_autopilot_on |
PARTIAL PANEL AVIONICS | number | partial_panel_avionics |
PARTIAL PANEL ELECTRICAL | number | partial_panel_electrical |
PARTIAL PANEL COMM | number | partial_panel_comm |
PARTIAL PANEL NAV | number | partial_panel_nav |
Two display entries are published, always both and always with these fixed identifiers, and
soi_display_id is always an empty string:
display_id | role | active_page resolution, first match wins |
|---|---|---|
primary_flight_display | AIRCRAFT_DISPLAY_ROLE_PFD | off if avionics master, general panel circuit or avionics circuit is zero; electrical_partial if partial-panel electrical is non-zero; avionics_partial if partial-panel avionics is non-zero; otherwise active |
multifunction_display | AIRCRAFT_DISPLAY_ROLE_MFD | off if avionics master or avionics circuit is zero; nav_partial if partial-panel nav is non-zero; comm_partial if partial-panel comm is non-zero; avionics_partial if partial-panel avionics is non-zero; otherwise active |
active_page is therefore a derived power and degradation label, not a page name. SimConnect
exposes generic simulation variables only; the aircraft-local gauge variables that a custom
multi-function display uses for its page and sensor-of-interest state are not reachable this way, so
no real page identity is available to publish. On registration the source records this as an
information-level log line.
The probe also logs its values once on the first payload and again on every change.
9.13 Values published without a source variable
These fields are written on every applicable frame from a constant, not from the simulator. A consumer cannot distinguish them from a measured value.
| Field | Constant |
|---|---|
AircraftAvionicsComponent.armed_lateral_mode | AIRCRAFT_AUTOPILOT_LATERAL_MODE_UNSPECIFIED |
AircraftAvionicsComponent.armed_vertical_mode | AIRCRAFT_AUTOPILOT_VERTICAL_MODE_UNSPECIFIED |
AircraftAvionicsComponent.armed_lateral_mode_label | empty string |
AircraftAvionicsComponent.armed_vertical_mode_label | empty string |
FuelSystemComponent.fuel_dump_rate | 0 |
FuelSystemComponent.fuel_total_flow_rate | 0 |
FuelSystemComponent.fuel_transfer_active | false |
FuelSystemComponent.refuel_active | false |
FuelSystemComponent.selected_feed_source_store_id | empty string |
FuelSystemComponent.active_dump_source_store_id | empty string |
ResourceStoreEntry.max_quantity | 0 for every store |
AircraftDisplayStateComponent.soi_display_id | empty string |
SimConnect exposes no transfer-path, dump-rate or fuel-flow variable in the set this module registers, so the fuel process values above have no available source. The armed autopilot modes have no source either: the module registers only engaged states.
10. Mapping defects in this revision
These are properties of revision 69d794b, not of SimConnect or of the HEAT schema. SIM-01 is the
recorded audit finding; the remaining rows are observations from the same reading of this revision
and carry no finding id.
| Ref | Field | Published value | Why it is wrong |
|---|---|---|---|
| SIM-01 | GenericAircraftComponent.barometric_altitude | KOHLSMAN SETTING MB in millibars | The field is an altitude. The module writes the altimeter’s pressure reference setting into it, unconverted, and never reads the INDICATED ALTITUDE variable it registers and caches. FWADataComponent.indicated_altitude and FWADataComponent.kohlsman_setting, the two fields that would carry these values correctly, are both left unset. Published altitude in this revision is materially wrong, and the repository’s own mapper test asserts the wrong value, so any fix must also change that test |
| none | AircraftLandingGearComponent.extended_percentage | GEAR TOTAL PCT EXTENDED as a fraction from 0 to 1 | The field is defined as a percentage where 0 is up and 100 is fully down. Fully extended gear publishes 1, not 100, so the value is a factor of 100 low |
| none | FWAControlSurfacesComponent.spoilers_position | SPOILERS HANDLE POSITION, a fraction from 0 to 1, truncated to a 32-bit integer | The field is an integer detent index. Truncation collapses every partial deployment to 0 and only fully deployed spoilers to 1, so intermediate spoiler positions are unobservable |
| none | RotaryWingDataComponent.tail_rotor_torque | TAIL ROTOR BLADE PITCH PCT as a fraction | A blade pitch percentage is not a torque. No unit conversion is applied and none would make it one. The repository’s rotary test asserts this behaviour |
| none | DynamicsComponent.magnitude | VELOCITY BODY Z converted to metres per second | The field is the magnitude of the velocity vector. Body-axis longitudinal velocity is signed and excludes the other two axes, so the value is negative in reverse and lower than the true speed in any sideslip or climb |
| none | AircraftEngineComponent.thrust_percentage | TURB ENG THROTTLE LEVER POSITION:1 as a fraction | The field is thrust as a percentage of maximum. A throttle lever position is a command, not a thrust, and the fraction is a factor of 100 low against a percentage field |
| none | AircraftEngineComponent.ignition | ENG COMBUSTION:1 | Ignition is published as a duplicate of engine_state from the same variable. The module registers no ignition variable, so ignition state is not actually observed |
| none | FWADataComponent.airspeed_calibrated | AIRSPEED INDICATED converted to metres per second | Indicated airspeed is published in the calibrated airspeed field. The two differ by instrument and position error, and the schema has no indicated-airspeed field to move it to |
| none | AirDataComponent.wind_velocity | AMBIENT WIND VELOCITY converted to metres per second | The field is annotated in knots. The module converts before writing, so the value is roughly half the number a knots-reading consumer expects. surface_wind_speed, which is defined in metres per second, is left unset |
| none | FWAInputComponent.autothrottle_active, afterburner_active, reverse_thrust_active | true when the source group has not been cached | Each is computed by comparing a nullable integer against zero. A null, meaning the Avionics or PropulsionControl group has not arrived yet, compares as not equal to zero and therefore publishes true. On a fixed-wing aircraft the first frames after connect can report the autothrottle engaged, the afterburner lit and reverse thrust deployed when none of that is known |
| none | SimulationFrame.capture_time and EntityState.timestamp | never set | Both builders expose the setter and neither is called, so state carries no in-band time. Only events carry a timestamp. Correlating state across modules depends entirely on the SDK envelope timestamp |
AircraftAvionicsComponent.active_lateral_mode_label disagreeing with active_lateral_mode under
backcourse hold, described in 9.7, is a schema limitation rather than a mapping error: the lateral
mode enumeration has no backcourse value.
11. Units and conventions
| Concept | Convention |
|---|---|
| Position | Decimal degrees, positive north and east, from the simulator’s own geodetic position. Narrowed to 32-bit float, which quantises at roughly 0.3 to 1 metre |
| Altitude | Metres above mean sea level for true altitude, metres above terrain for AGL. Both converted from feet at 0.3048 |
| Attitude | Degrees. Heading is true heading, not magnetic. Pitch and roll are the simulator’s own sign convention, passed through |
| Linear velocity and acceleration | Metres per second and metres per second squared, in the simulator’s world axes, converted from feet |
| Airspeed | Metres per second, converted from knots at 0.51444 |
| Mach | Dimensionless, passed through |
| Temperature | Degrees Celsius, passed through |
| Pressure | Millibars, passed through |
| Air density | Slugs per cubic foot, passed through unconverted, matching the field’s own annotation |
| Control positions and trims | Fractions from 0 to 1 as delivered by percent over 100, written without rescaling. Fields whose schema expects a percentage therefore read a factor of 100 low |
| Fuel quantity | US gallons, unconverted, with the unit enumeration set accordingly. Fill level is rescaled to a percentage in extra_data |
| Torque | Newton-metres for main rotor torque, converted from foot-pounds |
| Thrust | Newtons, converted from pounds-force at 4.44822 |
| Booleans | Any non-zero integer is true |
| Time base | Host wall clock, UTC Unix milliseconds. No simulator clock is read, and no simulation time is published |
| Frame ordering | simulation_tick increases by one per published frame and restarts at zero on each capture start, so it identifies a frame within a session only |
Values are passed through without range validation. The authority for the meaning of each simulation variable is the simulator vendor’s own SimConnect documentation; this module does not define or constrain it.
12. Error behaviour
| Condition | Behaviour |
|---|---|
Native SimConnect.dll missing from the variant’s directory | The backend throws FileNotFoundException naming the expected path before the wrapper loads. It surfaces as a connect failure, so the module retries forever rather than reporting a permanent configuration fault |
| Simulator not running at initialisation | Connect throws, logged as warning SimConnect connection attempt failed - will retry, reconnect loop starts. Initialisation still reports success |
| Publication cycle while disconnected | No frame, no log |
Publication cycle before the first Core payload | No frame, no log |
| Simulator sends its quit message | Warning SimConnect disconnected (sim quit), connection marked down, both system-event flags cleared, reconnect loop starts |
| Exception on the message pump thread | Warning SimConnect MSFS pump error - marking disconnected or SimConnect P3D pump error - marking disconnected, connection marked down, disconnect raised, pump thread exits, reconnect loop starts |
| SimConnect protocol exception, for example a rejected variable name | Debug SimConnect exception {Code} on send {SendId}. No state change, no retry, nothing published about the affected group |
| Reconnect attempt fails | Debug SimConnect reconnect attempt failed, delay doubles, capped at 30000 ms |
| Reconnect succeeds | Information SimConnect reconnected |
| Payload arrives for a data-source request id at or above 100 that no source claims | Debug Unhandled data-source request {RequestId} |
| Payload arrives for an unrecognised built-in request id | Error Unhandled data request {RequestId} |
CATEGORY is a value the module does not recognise | Aircraft type becomes unknown; neither fixed-wing nor rotary-wing components are published, and nothing is logged |
| Exception during frame construction | Returned as a faulted task. The SDK logs Error in module and the capture loop continues |
| Backend disposal throws because the simulator has already gone | Swallowed |
The debug-level handling of protocol exceptions is the significant one. Because definition layout is positional, a rejected variable name silently changes what every following field in that group means, and the only report of it is a debug log line.
13. Configuration affecting the interfaces
| Setting | Default | Interface effect |
|---|---|---|
RemoteHost | empty | Empty selects local connection with config index 0 and writes no file. A value writes SimConnect.cfg per section 7 and selects config index 1 |
RemotePort | 500 | Port written into that file. Ignored when RemoteHost is empty |
ReconnectIntervalMs | 5000 | First delay in the reconnect loop. Doubles per failure, capped at 30000 ms. Does not affect the initial connect attempt |
StartOnSimRunning | true | Whether becoming active on IF-CMSIMCONNECT-02 starts a capture session |
StopOnSimPaused | true | Whether becoming inactive on IF-CMSIMCONNECT-02 stops the active session |
StopOnSilence | false | Whether the silence timer may stop the session |
SilenceThreshold | 30 seconds | Data-idle duration the silence timer requires. Only consulted when StopOnSilence is set |
Nothing in the settings changes which simulation variables are registered, which units are requested, or which periods are used. Those are fixed in code, as is the 500 ms pump wait, the 2 second pump join on disposal, the 1 second silence-timer period, the 30000 ms reconnect cap, the 4096-byte remote receive size, and the 16-station cap in the Prepar3D weapons source.
The generic SDK settings also apply. Interval is the publication cadence and is re-read every
cycle; it does not change the simulator’s delivery rate. See
Manage capture modules for those, and
the Module SDK ICD for the lifecycle and envelope this module runs inside.
14. Compatibility and versioning
There is no protocol version negotiation. The module logs the application name and SimConnect version the simulator reports on open, and then proceeds identically whatever those values are. No version gate, capability check or feature test exists.
Compatibility rests on three assumptions, none of which is verified at runtime:
- Every registered variable name is accepted by the simulator with the requested unit string. A rejection is only debug-logged, and because layout is positional the group’s remaining fields shift and are misattributed.
- The vendor wrapper and the native client in the package match the installed simulator. The two packages are not interchangeable and the module cannot detect being paired with the wrong simulator.
- The managed wrappers are mixed-mode assemblies and cannot load into a collectible assembly load context. A host using a custom module load context must fall back to the non-collectible default context.
Variable coverage is a fixed list. Variables the simulator supports but the module does not register are absent; there is no way to extend the set through configuration.
15. Security considerations
The local interface is the simulator’s own SimConnect endpoint on the same workstation, with no authentication and no encryption. Any local process able to reach that endpoint can subscribe to the same data.
Remote mode increases the exposure: an unauthenticated, unencrypted IPv4 connection whose endpoint
the module writes in cleartext into SimConnect.cfg beside its own binaries, rewritten on every
connect attempt and never removed. Anyone able to read the module directory learns the remote host
and port; anyone able to write it can redirect the module to another host. Treat remote mode as
suitable only for a trusted, isolated network segment.
Captured content is aircraft state and, on Prepar3D, weapons employment. The aircraft title, ATC identity and transponder code identify the simulated aircraft rather than the operator, but a session still associates a named user with a training exercise. Restrict access to captured sessions according to the deployment’s own data-handling policy.
16. Conformance
- Install the package matching the simulator on that workstation and confirm the native client is
present in the variant’s
simconnectdirectory. Confirm on startup that the log recordsSimConnect connected towith the expected application name and a SimConnect version. - With the simulator loaded into a flight, confirm one entity appears, named with the aircraft title, and that its id is stable across a restart of HEAT Capture with the same aircraft.
- Confirm the aircraft type gate: with a fixed-wing aircraft, the three fixed-wing components are present and the rotary-wing component absent; with a helicopter, the reverse. With an aircraft whose category is none of the five recognised values, confirm neither set is published.
- Verify SIM-01 directly. Read the simulator’s altimeter setting and its indicated altitude, then confirm the published barometric altitude equals the altimeter setting in millibars and not the indicated altitude in metres. Retain that trace as the before state for any correction.
- Verify the scale defects in section 10 on a single frame: extend the gear fully and confirm gear
extension publishes
1; deploy spoilers to a partial detent and confirm spoiler position publishes0. - Confirm the first-frame boolean behaviour: with a fixed-wing aircraft, capture the first frames after a connect and check whether autothrottle, afterburner and reverse thrust are published as engaged before the avionics and propulsion groups have arrived.
- Pause the simulation and confirm the session stops when
StopOnSimPausedis set, then resume and confirm it starts again whenStartOnSimRunningis set. - Close the simulator while capturing. Confirm the sim-quit warning, then restart the simulator and confirm reconnection without restarting HEAT Capture, and that the reconnect log line appears.
- On the Prepar3D variant, arm the weapon system, fire from a station, dispense a countermeasure and change the fire-control target. Confirm one event per transition and confirm the countermeasure event carries an empty name.
- If remote mode is used, confirm
SimConnect.cfgis written beside the module binaries with the expected host and port, and that its presence is acceptable under the deployment’s own handling rules for network configuration.
17. Revision history
| Rev | Date | Product version | Change |
|---|---|---|---|
| 1 | 2026-09-02 | 69d794b | Initial issue. |