Skip to Content
This documentation is provided with the HEAT environment and describes this HEAT instance.

Data produced by HCP MACE

Lifecycle

Capture follows the MACE mission state, when AutoStartTransport is on (see Configure):

Mission stateWhat happens
RunningTransport, event source and scheduler start; the HEAT Capture session resumes
PausedCollectors stop, one final frame is published for whatever they already captured, the HEAT Capture session pauses
StoppedSame as Paused, then the transport drains its buffer and closes the HEAT Capture session
Loading / Initialized / Reset / UndefinedNo-op

Entity-state capture and event capture run as two independent loops, decoupled by a shared event buffer: a MACE callback (weapon fire, DIS collision/designator PDU) can enqueue an event at any time, on MACE’s own thread, independent of the periodic capture tick.

Operator attribution

HeatUserComponent.user_name (the authenticated HEAT Capture session user, in canonical GUID form) is attached only to the entity this MACE instance is actively flying:

entity.IsInternalEntity && entity.ManeuverState == ManeuverStateEnum.maneuver

ManeuverState is an active-control signal, not an identity claim; IsInternalEntity exists specifically to stop a remote DIS/TENA entity in a distributed simulation from being attributed to the local operator. ARMOR is a visual/output attachment in this model, not the control-input source - MACE remains the source of truth for what “controlled” means here.

Entity components

Populated when applicable, subject to the cadence and content settings in Configure:

ComponentSourceNotes
HeatUserComponentSee operator attribution aboveOnly on the locally-controlled entity
WorldPositionComponentPosition, orientationLatitude, longitude, altitude, heading, pitch, roll
DynamicsComponentLinear/angular velocity, acceleration, speeds
HealthComponentHealth, mobility-kill, kill flagsmax_health is hardcoded to 1.0 - MACE exposes no separate maximum
AirDataComponent / AircraftDataComponent / FwaDataComponentAir-domain extractionEnvironment and flight detail are independently optional; FwaDataComponent (control surfaces) is fixed-wing only
EmissionComponentActive emitter modesPer tick, toggleable
SensorContactsComponentPerceived radar contactsPer tick, toggleable - this is what an operator’s radar actually sees, not ground truth
ReceiverCharacteristicsComponent / ReceiverEnvironmentComponentReceiver mode dataCharacteristics are change-gated; environment publishes every tick
SignatureComponentRCS, EOIR modeIR-intensity normalization is unconfirmed against a reference
CombatStateComponentTeam affiliation, postures, EMCONcleared_hot has no MACE source and is never populated
IffComponentIFF modesModes 4/5 are flags only - MACE exposes no code or PIN for either
DataLinkComponentLink 16 / SADLHeader-level only; individual J-series message records are not consumed
UnitTypeComponent / ResourceStoresComponentEntity type, fuel and munitions
AircraftLightingComponent / GroundVehicleLightingComponentLighting stateMACE’s “on” maps only to high-beam - there is no separate low-beam signal to capture
LinkedEntityComponentReverse child-to-parent scan (MACE exposes no direct parent accessor)link_type is never set - no MACE signal distinguishes attachment kind
RadioComponentDIS transmitter PDU cacheFrequency, band, secure flag, selected flag; transmit frequency duplicates what EmissionComponent already carries for the same entity
CloudDataComponentWeather
⚠️

WeaponLoadoutComponent is never populated. MACE’s IHardpoint exposes no store/loadout field for this plugin to read, so weapon-station and magazine data - populated by some other plugins in this catalogue - has no MACE source here.

Slow-changing components (UnitType, Signature, ReceiverCharacteristics, CombatState, IFF, DataLink, Radio, and, when PlatformStateMode is OnChange, Health and the lighting/ TargetData/LinkedEntity group) are emitted only when their serialized bytes actually change. A component that disappears after having a value still emits one empty instance as an explicit removal marker, so a consumer can tell “gone” from “never sent.”

A tick with nothing to report - no entity due for publication and no event pending - publishes no frame at all, rather than an empty one. simulationTimeSeconds is therefore not a continuous per-tick counter from a consumer’s point of view; gaps in it correspond to genuinely idle ticks, not lost data.

Events

Every discrete occurrence emits a TrackingEvent (the authoritative verb) together with an EntityDataEvent carrying the same verb’s typed payload - always as a pair, never one without the other.

EventTrigger
FIREDMACE WeaponFire
DETONATIONMACE WeaponDetonation
HITMACE WeaponDamage
COLLISIONDIS CollisionPDU
LASEDDIS DesignatorPDU
STATE_CHANGED (grounded/airborne, stall, overspeed, weapon-selection)Per-tick state diff
TARGETLOCKED / TARGETRELEASEDPer-tick target-assignment diff
RADAR_EMISSION_STARTED / RADAR_EMISSION_STOPPEDPer-tick transmitting-emitter diff
ESM_CONTACT_DETECTED / ESM_CONTACT_LOSTPer-tick RWR contact diff
JAMMEDPer-tick jamming-onset diff
⚠️

Jamming has no stop event. Only the onset (JAMMED) is emitted; there is no corresponding “jamming stopped” verb in this version, so a consumer cannot tell from events alone when a jamming condition ends.

Transition events (everything below HIT in the table above) are detected by diffing each entity’s state between ticks, at the global CaptureIntervalMs cadence - always, regardless of that entity’s own publish interval setting. A transition that starts and fully ends between two ticks of a raised CaptureIntervalMs is missed; callback-driven events (fire, detonation, hit, collision, lased) are never subject to this and are always captured.

Known extraction gaps

Beyond the per-component notes above, confirmed directly in source:

  • The MACE-API-reading code itself (translating IPhysicalEntity/IMode into a snapshot) has no fixture or mock test harness - only the pure logic downstream of it (conversion math, id hashing, enum mapping, event builders, the change gate) has unit coverage.
  • Save/load entity-id stability has not been validated against a live save/load cycle.
  • Jamming victim-list resolution has not been exercised against a live jamming lock.
Opens your browser's print dialog. Choose "Save as PDF" as the destination.