Versioning and compatibility
Version numbering
The version number (v0.37.1 at the time this page was verified) is computed by
GitVersion from Conventional Commits
on main: a fix: commit bumps the patch version, feat: bumps minor, and a commit carrying a
BREAKING CHANGE: footer bumps major. The version is not hand-assigned; it is a direct function
of the commit history since the last tag.
The project has not cut a 1.0 release. Every published version so far is 0.x, so under semantic
versioning’s own convention the public contract, schema included, has not yet been declared
stable. Treat a minor version bump as a signal to re-check the Message reference
diff, not only a patch bump.
What a schema change is allowed to do
The schema follows two protobuf-standard practices, visible directly in the .proto files:
- A retired field or message number is
reserved, never reassigned.Componentreserves field numbers 6 to 12 for a retiredLightsComponent,ControlComponentandEngineComponent;WorldPositionComponentandResourceStoreEntrycarry their ownreservedranges for fields removed in earlier revisions. A number, once shipped, is never given a new meaning. - A new field takes the next unused number in the appropriate range; see the field-numbering convention in Schemas. Adding a field is additive and does not require a major version bump under Conventional Commits.
That combination is what makes proto3 wire-compatible across versions in both directions:
| Situation | Behaviour |
|---|---|
| Older consumer reads a frame from a newer producer | Unknown fields are silently ignored. New components and new event types do not appear to the older consumer. |
| Newer consumer reads a frame from an older producer | Fields the older producer never set decode as proto3 defaults: 0, empty string, empty list, or absent for an optional field. |
A field the schema marks optional is missing | Distinguishable from an explicit default; several messages document what absence means specifically (for example, WeaponStation.quantity absent means “not tracked”, 0 means “empty station”). Read the field’s description in Message reference, not only its type. |
A oneof (Component.data, EntityDataEvent.event_data, or any nested oneof) has no branch set | The consumer’s generated code exposes this as an explicit “none set” case in every language; check it before assuming a branch is populated. |
What is not covered by this guarantee
- Renaming or repurposing a field number is not something the schema does, but nothing in protobuf prevents a future contributor from doing it incorrectly. If you observe a field whose meaning appears to have changed between two versions without a number change, treat that as a defect and report it; it is not an intended compatibility mechanism.
- A component or event being added is not retroactive. A capture recorded before
WearableBioSensorComponentexisted has noWearableBioSensorComponentframes to find; this is a schema addition, not missing data within its own scope. - This page describes the ProtoLib schema only. The transport that carries these messages, and that transport’s own compatibility rules (for example, HEAT Capture’s frame-publish WebSocket), is documented in that product’s Interface Control Document, not here.
Checking what version you are reading
Every generated package embeds the same version GitVersion produced. There is no runtime message
or field carrying the ProtoLib schema version; if you need to record which schema version produced
a given capture, record the package version from your build (for example, the NuGet package
version or the wheel’s heat_protolib version) alongside the data.