Skip to content
Tim Mcguinness edited this page Apr 24, 2026 · 5 revisions

FAQ

What is VTX?

VTX is an open, self-describing binary format for real-time state data, plus a C++20 SDK for writing, reading, diffing, and inspecting it. VTX is the container; producers (games, engines, third-party capture tools) write into it. See Home for the elevator pitch.

Is VTX an acronym?

No. It's the format name.

Is VTX a game format?

It was born in games and has been validated across multiple game engines, but it is not a game format. VTX is a generic real-time state format. The same format is designed to work for a MOBA, an FPS, a racing sim, a sports broadcast, a simulation, or any other system that produces structured state at real-time cadence.

Domain-specific meaning is layered on top through contextual schemas, not baked into the format. See Concepts.

Does VTX store game assets (meshes, textures, audio)?

No. VTX is a pure state data layer. It describes what is happening, but the visual / audio assets themselves live in separate systems. VTX files carry soft references and unique identifiers so downstream tooling can resolve the right assets at runtime.

What engines / platforms does VTX support?

The SDK is pure C++20 with no engine dependency. It builds on Windows and Linux. See Runtime Contracts, Platform and toolchain support for the tier breakdown.

Protobuf and FlatBuffers bindings exist for C++, Python, Go, Rust, Java, JavaScript, and more, so external consumers don't need to be C++.

VTX has been validated in production across multiple engines via real-world captures (CS2, Rocket League, and others).

Protobuf or FlatBuffers, which should I use?

Both are supported out of the box. Pick based on workload:

  • Protobuf: smaller files, better for storage / network / archival.
  • FlatBuffers: faster diffs and data access, better for real-time playback.

Neither wins universally. The file's magic bytes announce which one was used, and VTX::OpenReplayFile auto-detects, so integrators don't need to know in advance. See File Format, Serialisation backends.

Can I plug in a different serialisation format?

Yes. Implement the SDK's serialisation interface. You'll also need a matching diff implementation for the new format. Out-of-the-box we support Protobuf and FlatBuffers.

Schemaless formats (Cereal, Bits) were evaluated but rejected: the diffing system requires files to be self-describing.

How does seeking work?

Each VTX file has a footer that maps timestamps and frame indices to file byte offsets. Scrubbing binary-searches that index (O(log n)) and decompresses the one chunk that contains the target frame.

It is not literally O(1): "instant" scrubbing is a tiny index lookup plus one chunk decompress. Sub-millisecond when the target chunk is warm in the reader's cache; tens of milliseconds on a cold seek while the chunk decompresses. The cost scales with chunk size, not with total file size. See File Format, Footer / time index.

Is the VTX SDK thread-safe?

Default rule: no SDK object is safe for concurrent use from multiple threads unless documented otherwise. ReaderChunkState is thread-safe by design; everything else requires external synchronisation. See Runtime Contracts, Thread safety.

How long is a const Frame* valid?

Only until the next reader call that can evict the chunk containing that frame. Don't cache frame pointers across calls. If you need to hold a frame, copy it with the GetFrame(i, Frame& out) form. See Runtime Contracts, Ownership and lifetime.

How does the SDK report errors?

Three styles, depending on the surface:

  • Reader open: status-object. OpenReplayFile never throws; check ctx.operator bool() and read ctx.GetError().
  • Writer fatal setup errors: exceptions (std::runtime_error).
  • Deserialiser: compile-time policy (StrictErrorPolicy / LenientErrorPolicy / SilentErrorPolicy) selected by template parameter.

See Runtime Contracts, Error handling.

Is the format stable? What versioning guarantees do you give?

VTX is pre-1.0. Until 1.0, API, format, and schema can change incompatibly between releases. After 1.0, versioning follows the policy in Stability: SemVer on the API, explicit format-version bumps for breaking on-disk changes, and schema-level breaking-change detection via the Schema Creator.

Pin a specific tag if stability matters to you during the pre-1.0 period.

Can I read a VTX file written years ago?

Yes, that's a core design goal. The schema is embedded in every file. A reader today can decode a file recorded earlier without external documentation or the original application code. Schema evolution is backward-compatible: new fields can be added without breaking older readers. For the exact rules see Stability, Schema evolution.

If the on-disk format hits a breaking major-version bump (rare, announced), we ship a conversion tool.

What happens if my cache window is the wrong size?

It can hurt more than no cache at all. A mis-sized reader cache can be ~59 % slower than running without a cache. This is the single sharpest performance edge in the SDK.

Guidance in Performance, Cache-window sizing. Short version: measure before tuning, and when unsure, zero cache beats a wrong cache.

What's the memory footprint of the reader?

Dominated by the chunk cache. Roughly (backward_window + forward_window + 1) * average_decompressed_chunk_size. A 10 MB compressed chunk typically expands to ~25-40 MB. See Runtime Contracts, Memory model.

What are the hard limits?

  • Max frames per file: 2^31 - 1 (int32 frame index).
  • Default chunk rolls at 1000 frames or 10 MB (whichever first); both configurable.
  • Max file size: no explicit cap; bounded by 64-bit byte offsets in the footer.

See Runtime Contracts, Hard limits.

Is VTX just a replay format?

No. It works equally well as:

  • A streaming format: chunks flushed live, consumed by downstream tools with low latency.
  • A storage format: full matches persisted for replay, analytics, or training.

Same format, same reader, same tooling. A tool written once reads either.

How do I build a contextual schema for my title?

Use the Schema Creator to author schema.json directly. That's the supported path today.

Engine-specific code generation (scraping reflection data from an engine to emit a schema automatically) is a tooling pattern we use internally, but the open-source SDK does not ship that bridge. If you want auto-generated schemas for your engine, you will be writing that part. See Concepts, Schema authoring.

Where do I report a bug or a security issue?

How do I contribute?

See CONTRIBUTING.md. PRs welcome.

What's the licence?

Apache-2.0. See LICENSE and NOTICE / THIRD_PARTY_LICENSES.md for third-party attribution.

Clone this wiki locally