How to Record and Play Back Simulation Data

Configure and control the CRecorder static class to capture runtime data to disk.

This guide explains how to configure the CRecorder class to capture simulation data efficiently, using frame-based flushing and change/receive-based filtering.

1. Understand CRecorder

CRecorder is a static, globally accessible recording manager responsible for setting up, configuring, and controlling the capture of runtime data into persistent storage. It provides:

The recorder is designed to minimize I/O overhead and reduce redundant writes while preserving deterministic frame-aligned recording.

Design characteristics: fully static interface, centralized state, frame-aware flushing, selective data capture, optimized for high-rate systems.

2. Know the Public API

class CRecorder
{
public:
    static void StartRecording();
    static void StopRecording();

    static void SetRecorderPath(const char* path);
    static void SetRecordingFramesFlush(int iRecordingFlushEveryMinorFrame);
    static void SetRecordOnlyIfChanged(int bRecordOnlyIfChanged);
    static void SetRecordingProperties(const char* elementName,
                                       int64_t engSize = -1,
                                       int64_t rawSize = -1,
                                       bool bRecordOnlyIfReceived = false);
    static void AddRecordingItem(const char* itemName,
                                 int64_t engSize = -1,
                                 int64_t rawSize = -1,
                                 bool bRecordOnlyIfReceived = false);
};
MethodDescription
StartRecording()Initializes internal buffers, opens output files, and begins frame-aligned recording.
StopRecording()Stops recording, flushes remaining buffered data, and closes resources safely.
SetRecorderPath(path)Defines the directory or base path where recording files will be created.
SetRecordingFramesFlush(n)Controls how often buffers are flushed to disk (every n minor frames). Lower values increase safety, higher values improve performance.
SetRecordOnlyIfChanged(flag)Default is true. If enabled, data is recorded only when its value changes between frames, reducing file size and I/O load.
SetRecordingProperties(...)Defines metadata for a logical element: explicit engineering/raw size and optional "record only if received" gating.
AddRecordingItem(...)Registers a single recordable entity (stream/block/element) by name, with size control and conditional recording (see below).

3. Choose Size Control Settings

When calling AddRecordingItem or SetRecordingProperties, control how much data is captured per item:

Parameter ValueEffect
engSize = -1Use the predefined engineering size as defined in the project DBSim.
engSize = 0Disable engineering value recording.
engSize > 0Record exactly the specified number of bytes for the engineering value.
rawSize = -1Use predefined raw size as defined in the project DBSim.
rawSize = 0Disable raw value recording.
rawSize > 0Record the exact number of raw bytes specified.

Use bRecordOnlyIfReceived to write an item only if new data arrived during the current frame — this prevents recording stale or repeated values in event-driven or bus-based streams.

4. Apply Recording Policy Controls

Frame-Based Flushing

Recording is aligned to simulation minor frames. Choose the flush interval based on your tradeoff:

Change-Based Filtering

Enable SetRecordOnlyIfChanged(true) so identical consecutive values are not written again — especially effective for slow-changing or state-like signals.

Receive-Based Filtering

Set bRecordOnlyIfReceived to ensure an item is recorded only when fresh data is received during the frame, preventing duplication of stale values.

5. Follow the Typical Usage Flow

// Configure recorder
CRecorder::SetRecorderPath("C:/records/session1");
CRecorder::SetRecordingFramesFlush(10);
CRecorder::SetRecordOnlyIfChanged(true);

// Define properties
CRecorder::SetRecordingProperties("FlightModel", 64, 64);
CRecorder::AddRecordingItem("Altitude", 8, 8);
CRecorder::AddRecordingItem("Velocity", 8, 8);

// Start capture
CRecorder::StartRecording();

// ... simulation runs ...

CRecorder::StopRecording();

6. Follow Best Practices

7. Treat the Recorder as Infrastructure

CRecorder should be treated as an infrastructure service rather than a business-logic component. Modules register their items declaratively, while the recorder enforces consistent storage format and timing alignment.