Interface control document
1. Identification
| Item | Value |
|---|---|
| Document | ICD-HCPVBS-001 rev 1 |
| Product | HCP VBS (HCPVBS Gears Studio component) |
| Product versions covered | v1.3.0 |
| Peer | HEAT Capture |
| Data model | HEAT ProtoLib, C++ headers bundled at include/HCPVBS/HEATProtolib/. This bundled copy carries no version marker readable from the hcp-VBS repository; the TrackingEventType and component definitions referenced in this document were verified directly against HEAT-ProtoLib at its main branch, protos/HEAT/Proto/Simulation/TrackingEvent.proto and cpp-ffi/include/HEAT/Proto/Builders.h, and the enum values agree exactly with what hcp-VBS sends. |
| Date | 2026-09-02 |
| Owner | VRAI Simulation |
2. Scope
HCP VBS observes a running VBS4 mission and publishes entity state and simulation events to HEAT Capture. It starts and stops a HEAT Capture session around the VBS4 mission lifecycle.
It does not control VBS4 entities and does not consume vehicle inputs: every VBS4 mission runs identically whether or not HCP VBS is loaded. It receives no commands from HEAT Capture beyond what its own session-status polling reads back.
The plugin implements two independent publish transports, only one of which currently has a working peer:
- WebSocket (IF-HCPVBS-02) - functional against current HEAT Capture.
- Named pipe (IF-HCPVBS-03) - implemented in the plugin, targeting a
\\.\pipe\HEATCollectorservice that predates HEAT Capture’s current REST/WebSocket interface. Nothing in current HEAT Capture connects to this pipe. It is documented here because it exists in the shipped binary and its shipped default configuration selects it, not because it is a supported integration path.
3. Interface inventory
| ID | Name | Direction | Transport | Peer |
|---|---|---|---|---|
| IF-HCPVBS-01 | Session control | Product to peer | HTTP REST, no TLS | HEAT Capture |
| IF-HCPVBS-02 | Frame and event publish | Product to peer | WebSocket, no TLS | HEAT Capture |
| IF-HCPVBS-03 | Frame and event publish (named pipe) | Product to peer | Win32 named pipe | None currently - see Section 2 |
4. IF-HCPVBS-01 Session control
4.1 Transport and addressing
Plain HTTP. Base address is http://<websocket.hostname>:<websocket.port> from
HCPVBSConfig.json (default http://localhost:50001, which does not match HEAT Capture’s own
default port - see Configure). Endpoint paths are configured
separately: session.startEndpoint and session.stopEndpoint default to
/api/session/start-session and /api/session/stop-session; the current-session GET path is
fixed in the plugin at /api/session/current-session and is not configurable.
4.2 Connection lifecycle
HCP VBS issues one POST to startEndpoint when VBS4 calls Component_OnStart (component
load), followed immediately by one GET to the current-session endpoint, whose result is
cached. It issues one POST to stopEndpoint when VBS4 calls Component_OnStop (component
unload). There is no retry and no keep-alive on this interface; a failed start leaves the plugin
without a session, but it continues attempting to publish over IF-HCPVBS-02/03 regardless.
4.3 Authentication
None presented by the plugin. HEAT Capture requires a signed-in user for every /api/session/*
call; the plugin does not surface or handle that requirement beyond the HTTP call failing.
4.4 Messages
| Endpoint | Method | Purpose | Auth |
|---|---|---|---|
/api/session/start-session | POST | Start a HEAT Capture session | Signed-in user required by HEAT Capture |
/api/session/stop-session | POST | Stop the active session | Signed-in user required by HEAT Capture |
/api/session/current-session | GET | Fetch and cache the current session | Signed-in user required by HEAT Capture |
4.5 Data elements
The plugin parses the current-session response into its own SessionResponse structure
(session id, project, session template, node instances, metadata) but only uses it to decide
whether a session is active; none of these fields are re-published on IF-HCPVBS-02/03.
4.6 Timing
Once per component load/unload; not repeated on a timer.
4.7 Error behaviour
| Condition | Observable | Product behaviour |
|---|---|---|
| No user signed in to HEAT Capture | HTTP POST fails | Start() returns false; the plugin does not retry and proceeds to attempt frame publish anyway |
| Wrong host or port | HTTP POST fails or times out | Same as above |
5. IF-HCPVBS-02 Frame and event publish (WebSocket)
5.1 Transport and addressing
WebSocket over plain HTTP (ws://, no TLS). The connection URL is
<websocket.address><websocket.publishEndpoint> (default ws://localhost:50001/ws/publish as
shipped; must resolve to HEAT Capture’s actual /ws/publish endpoint - see
Configure). websocket.hostname/websocket.port are not used to
build this URL; they only affect IF-HCPVBS-01.
5.2 Connection lifecycle
Opened once when VBS4 calls Component_OnStart. Automatic reconnect with backoff delays of
1, 2, 4, 8, then 10 seconds repeating. No explicit close call is made on component unload beyond
process teardown.
5.3 Authentication
None presented by the plugin. HEAT Capture requires a signed-in user for the WebSocket handshake to succeed at all.
5.4 Messages
One binary WebSocket frame per SimulationFrame, Any-wrapped (the type_url is set by the
frame’s own serialize_as_any()), for both the periodic entity-state frame and every
independent tracking event. HEAT Capture closes the connection on any frame larger than 10 MiB
and ignores text frames.
5.5 Data elements
See Data produced for the full entity component and tracking event catalogue.
5.6 Timing
Entity-state frames: fixed 0.1 second period (10 Hz); not configurable in this version despite a
collection.intervalSeconds setting that appears to control it - see
Configure. Tracking events: sent immediately as VBS4 raises the
underlying callback, independent of the entity-state cadence.
5.7 Error behaviour
| Condition | Observable | Product behaviour |
|---|---|---|
| Connection lost | onclose in the plugin’s console log | Automatic reconnect per the backoff schedule above; frames generated while disconnected are not buffered and are lost |
| Frame exceeds 10 MiB | HEAT Capture closes the connection | Reconnect per the backoff schedule; the offending frame is lost |
6. IF-HCPVBS-03 Frame and event publish (named pipe)
6.1 Transport and addressing
Win32 named pipe, message-mode, outbound-only from the plugin’s perspective. Pipe name is
namedpipe.pipeName in HCPVBSConfig.json (default \\.\pipe\HEATCollector).
6.2 Connection lifecycle
HCP VBS creates the pipe as a server (CreateNamedPipeA) and waits for a client to connect.
No component of current HEAT Capture connects to this pipe as a client. With this transport
selected, every publish attempt fails; because autoReconnect is unconditionally forced on, the
plugin tears down and recreates the pipe on every failed write - once per collection tick,
indefinitely - without ever raising an error visible above informational log level.
6.3 Authentication
None. Default Win32 security descriptor on the pipe handle.
6.4 Messages
Each SimulationFrame is serialized to raw (non-Any) protobuf bytes, base64-encoded with a
trailing newline, and written to the pipe as one message.
6.5 Data elements
Same entity components and tracking events as IF-HCPVBS-02 - see Data produced.
6.6 Timing
Same fixed 10 Hz entity-state cadence as IF-HCPVBS-02.
6.7 Error behaviour
| Condition | Observable | Product behaviour |
|---|---|---|
| No client ever connects (current, permanent state against HEAT Capture) | Console log line Write failed, attempting reconnection, repeating | Pipe is destroyed and recreated; no data reaches any peer |
7. Data model reference
Entities carry SimulationFrame → Entity → Component messages: WorldPositionComponent,
TransformComponent, DynamicsComponent, GroundVehicleControlComponent,
ResourceStoresComponent, WeaponLoadoutComponent, AircraftEngineComponent,
GroundVehiclePowertrainComponent, CombatStateComponent, IffComponent,
LinkedEntityComponent, HealthComponent, HeatUserComponent, RotaryWingDataComponent,
FwaDataComponent, GenericAircraftComponent, AirDataComponent, UnitTypeComponent, and
CloudDataComponent on the synthetic environment entity. Events carry TrackingEvent with
FiredEvent, JsonEventData, or BookmarkEvent payloads depending on type. See
Data produced for which VBS trigger populates which component or event,
and which schema fields this plugin never populates.
8. Units, frames and conventions
| Concept | Convention |
|---|---|
| Linear units | Metres; fuel in litres when tank capacity is known, otherwise percent; ammunition in rounds |
| Angular units | Degrees in VBS’s own API; converted to radians/second for DynamicsComponent.angular_velocity. Orientation is always sent as a quaternion, never as raw Euler angles |
| Coordinate frame | WorldPositionComponent carries absolute geodetic position. TransformComponent’s position and rotation are in the local East-North-Up (ENU) tangent plane at the entity (or, for a turret/mounted entity, relative to its parent’s frame) - not the ECEF global frame. The rotation quaternion is body-to-ENU, derived from VBS heading/pitch/roll via an intrinsic Z-Y-X composition documented in MathUtils::ToQuaternion |
| Geodetic datum | WGS 84; altitude is explicitly converted to the WGS84 ellipsoid reference before use |
| Time base | Wall-clock UTC milliseconds on SimulationFrame.capture_time; AAR bookmark timestamps are AAR-relative seconds, not wall clock |
| Endianness | Not applicable - payloads are protobuf, not a fixed binary layout |
9. Configuration affecting the interface
| Setting | Interface effect |
|---|---|
communication.type | Selects IF-HCPVBS-02 ("websocket") or IF-HCPVBS-03 ("namedpipe") - only the former currently reaches a peer |
websocket.address, websocket.publishEndpoint | IF-HCPVBS-02’s connection URL |
websocket.hostname, websocket.port | IF-HCPVBS-01’s base URL only |
session.startEndpoint, session.stopEndpoint | IF-HCPVBS-01’s POST paths |
namedpipe.* | IF-HCPVBS-03’s pipe name, buffer size and timeout; autoReconnect cannot actually be disabled |
collection.captureEnabled | Gates whether IF-HCPVBS-02/03 send anything at all |
EntityDenyList.json | Which entities are excluded from every frame and event on IF-HCPVBS-02/03 |
See Configure for the full settings reference.
10. Compatibility and versioning
Documented against hcp-VBS v1.3.0 and VBS4 25.1+. HEAT Capture’s REST and WebSocket surface
is the current interface; there is no version negotiation on either side. A SimulationFrame
with components a given HEAT Capture build does not recognise is expected to be tolerated as
unknown protobuf fields, consistent with how HEAT ProtoLib messages evolve elsewhere in this
catalogue - this plugin does not add or rely on any interface-level version check of its own.
11. Security considerations
Neither transport uses TLS. IF-HCPVBS-01 and IF-HCPVBS-02 rely entirely on HEAT Capture’s own signed-in-user requirement; the plugin presents no credential of its own. Treat network isolation between the VBS4 workstation and the HEAT Capture workstation as the security boundary, consistent with HEAT Capture’s own security guidance - see HEAT Capture’s web API. IF-HCPVBS-03 (named pipe) is local-machine-only by construction and moot while it has no peer.
12. Conformance
- Set
communication.typeto"websocket"and correct the port, per Configure. - Sign in to HEAT Capture, then start VBS4 with the component loaded. Confirm
onopenin the console log. - Start a VBS4 mission. Confirm HEAT Capture’s session view shows an active session for the VBS4 workstation.
- Spawn or observe an existing VBS4 entity. Confirm it appears in HEAT Capture within one collection tick (about 0.1 seconds).
- Fire a weapon at a target that will explode on impact. Confirm a
FIREDevent, then anAMMO_HITandDETONATIONevent pair, are observable on the HEAT Capture side. - End the VBS4 mission. Confirm the session stops on the HEAT Capture side without requiring a VBS4 restart.
13. Revision history
| Rev | Date | Product version | Change |
|---|---|---|---|
| 1 | 2026-09-02 | v1.3.0 | Initial issue. |