-
Notifications
You must be signed in to change notification settings - Fork 0
SDK API
A thin overview of the public API surface plus copy-pasteable recipes for common integration tasks. The authoritative reference is docs/SDK_API.md in the repo; runnable sample programs live in samples/ and are described in docs/SAMPLES.md.
For the behavioural contracts that sit alongside these calls (thread safety, ownership, error handling, memory, limits) see Runtime Contracts.
| Header | Purpose |
|---|---|
vtx/reader/core/vtx_reader_facade.h |
OpenReplayFile, IVtxReaderFacade, ReaderContext, ReaderChunkState
|
vtx/writer/core/vtx_writer_facade.h |
CreateFlatBuffersWriterFacade, CreateProtobuffWriterFacade, IVtxWriterFacade, WriterFacadeConfig
|
vtx/differ/core/vtx_differ_facade.h |
VtxDiff::CreateDifferFacade, PatchIndex, DiffOptions
|
vtx/writer/core/vtx_data_source.h |
IFrameDataSource for streaming producers into the writer |
vtx/common/vtx_error_policy.h |
StrictErrorPolicy, LenientErrorPolicy, SilentErrorPolicy
|
vtx/common/vtx_types.h |
Frame, PropertyContainer, FlatArray<T>, VtxFormat
|
Reader factories return std::unique_ptr<IVtxReaderFacade>. Writer factories return std::unique_ptr<IVtxWriterFacade>. OpenReplayFile returns a ReaderContext by value that owns the reader internally.
#include "vtx/reader/core/vtx_reader_facade.h"
VTX::ReaderContext ctx = VTX::OpenReplayFile("replay.vtx");
if (!ctx) {
std::cerr << "open failed: " << ctx.GetError() << "\n";
return 1;
}
int32_t total = ctx->GetTotalFrames();
// Sync read. Pointer is valid until the next call that can evict the chunk.
const VTX::Frame* frame = ctx->GetFrameSync(0);
for (const auto& bucket : frame->GetBuckets()) {
for (size_t i = 0; i < bucket.entities.size(); ++i) {
const auto& entity = bucket.entities[i];
const auto& uid = bucket.unique_ids[i];
// entity.float_properties[idx], entity.vector_properties[idx], ...
}
}std::vector<VTX::Frame> frames;
ctx->GetFrameRange(0, 99, frames); // frames 0..99 (returned by value)
auto window = ctx->GetFrameContext(500, 5, 5); // frames 495..505The range / context forms copy frames out and are always safe to hold.
GetFrameSync returns a pointer into the chunk cache, which may be evicted. If you need to keep a frame past the next reader call, use the copy-out form:
VTX::Frame frame;
if (!ctx->GetFrame(42, frame)) {
// invalid frame index, or chunk load failed
}
// `frame` is caller-owned and stays valid regardless of cache state.Default cache window favours sequential playback. For random-access UIs, widen the window so your working set fits.
ctx->SetCacheWindow(/*backward=*/ 8, /*forward=*/ 8);
// Before a known seek, prefetch the target chunk.
ctx->WarmAt(target_frame_index);
const VTX::Frame* frame = ctx->GetFrameSync(target_frame_index);If the cache is consistently mis-sized against your workload, it can be up to 59% slower than no cache at all. See Performance, Cache-window sizing.
Schema-driven lookup rather than hard-coded indices:
auto cache = ctx->GetPropertyAddressCache();
auto schema = ctx->GetContextualSchema();
// Cache maps human names ("Health") to (container type, index) pairs.
// Full usage is covered in docs/SDK_API.md.VTX::FileHeader header = ctx->GetHeader();
// header.replay_name, header.replay_uuid, header.recorded_utc_timestamp
// header.version.format_major / format_minor / schema_version
// header.custom_json_metadata
VTX::FileFooter footer = ctx->GetFooter();
// footer.total_frames, footer.duration_seconds
// footer.chunk_index (seek table), footer.events (timeline events)
const auto& seek_table = ctx->GetSeekTable();
for (const auto& e : seek_table) {
// e.chunk_index, e.start_frame, e.end_frame, e.file_offset, e.chunk_size_bytes
}ReaderChunkState is the one reader-adjacent surface that's safe to poll from a thread other than the one driving the reader. Useful for debug overlays.
VTX::ReaderChunkSnapshot snap = ctx.chunk_state->GetSnapshot();
// snap.loaded_chunks, snap.loading_chunks#include "vtx/writer/core/vtx_writer_facade.h"
VTX::WriterFacadeConfig config;
config.output_filepath = "output.vtx";
config.schema_json_path = "schema.json";
config.replay_name = "My Replay";
config.chunk_max_frames = 1000; // chunk rolls at whichever hits first
config.chunk_max_bytes = 10 * 1024 * 1024;
config.use_compression = true;
config.default_fps = 60.0f;
auto writer = VTX::CreateFlatBuffersWriterFacade(config);
// or: VTX::CreateProtobuffWriterFacade(config);
while (simulation_is_running) {
VTX::Frame frame = BuildFrameFromYourState();
VTX::GameTime::GameTimeRegister time;
time.game_time = current_game_time_seconds;
time.utc_timestamp = current_unix_timestamp;
writer->RecordFrame(frame, time);
}
writer->Flush(); // push the in-progress chunk to disk
writer->Stop(); // finalise: write footer + embedded schemaA frame contains one or more buckets (Entity / BoneData / Events / Stats). Each bucket carries aligned unique_ids and entities (PropertyContainers) whose property slots are defined by your schema.
VTX::Frame frame;
auto& world = frame.CreateBucket("World");
world.unique_ids.push_back("player_001");
VTX::PropertyContainer entity;
entity.float_properties.push_back(100.0f); // slot 0: Health
entity.vector_properties.push_back({1.0, 2.0, 3.0}); // slot 0: Position
entity.int32_arrays.AppendSubArray({10, 20, 30}); // slot 0: Inventory
world.entities.push_back(std::move(entity));Slot indices are determined by the schema you authored in the Schema Creator.
When you have a pull-style data source (JSON dump, third-party demo file, live feed), implement IFrameDataSource and drive the writer from it.
#include "vtx/writer/core/vtx_data_source.h"
class MyDataSource : public VTX::IFrameDataSource {
public:
bool Initialize() override;
bool GetNextFrame(VTX::Frame& out_frame,
VTX::GameTime::GameTimeRegister& out_time) override;
size_t GetExpectedTotalFrames() const override; // 0 if streaming / unknown
};
MyDataSource src;
src.Initialize();
VTX::Frame frame;
VTX::GameTime::GameTimeRegister time;
while (src.GetNextFrame(frame, time)) {
writer->RecordFrame(frame, time);
}
writer->Flush();
writer->Stop();#include "vtx/differ/core/vtx_differ_facade.h"
auto differ = VtxDiff::CreateDifferFacade(VTX::VtxFormat::FlatBuffers);
// Copy frame A out before asking for B -- getting B may evict A's chunk.
auto raw_a = ctx->GetRawFrameBytes(frame_a);
std::vector<std::byte> bytes_a(raw_a.begin(), raw_a.end());
auto raw_b = ctx->GetRawFrameBytes(frame_b);
VtxDiff::DiffOptions opts;
opts.compare_floats_with_epsilon = true;
opts.float_epsilon = 1e-5f;
VtxDiff::PatchIndex patch = differ->DiffRawFrames(bytes_a, raw_b, opts);
for (const auto& op : patch.operations) {
// op.Operation (Add/Remove/Replace/ReplaceRange), op.ContainerType,
// op.Path, op.ActorId
}Deserialisation paths take a policy as a template parameter. Shipped in vtx/common/vtx_error_policy.h:
| Policy | Behaviour on missing/mismatched field |
|---|---|
StrictErrorPolicy |
Throws std::runtime_error. Use for critical data. |
LenientErrorPolicy |
Warns to stderr, leaves variable at default. Good for debug loads. |
SilentErrorPolicy |
No-op. Highest throughput. Use only when integrity is guaranteed elsewhere. |
See Runtime Contracts, Error handling for where each style surfaces.
-
VTX::Frame— one or moreBuckets, each holding alignedunique_idsandentities. -
VTX::PropertyContainer— the per-entity SoA container. Scalar vectors (bool_properties,int32_properties,float_properties, ...), spatial (transform_properties,vector_properties,quat_properties), arrays (int32_arrays,float_arrays, ..., allFlatArray<T>), and nested (any_struct_properties,map_properties). Plusentity_type_idandcontent_hash. -
FlatArray<T>— Structure-of-Arrays container with sub-array support.AppendSubArray({...})/GetSubArray(i)/PushBack(subarray_idx, value). -
VTX::VtxFormat—FlatBuffers,Protobuf, orUnknown. -
VTX::GameTime::GameTimeRegister—game_time(float seconds) +utc_timestamp.
- Full reference with every method:
docs/SDK_API.md. - Runnable programs for every recipe above:
samples/, walkthrough indocs/SAMPLES.md. - Integration examples for real engines:
tools/integrations/. - Contracts and gotchas: Runtime Contracts.
- Hot-loop performance: Performance.
VTX is an open, self-describing binary format for real-time state data. Apache-2.0. (c) 2026 Zenos Interactive.