Skip to content

Sensors

Sensors are continuous streams of numerical (or boolean) values recorded over the course of a session. Where Custom Events capture discrete moments, sensors capture trends — framerate over time, a participant's heart rate, an app-specific stamina bar, the headset's pitch as they look around.

All recorded sensor data is displayed as graphs on the session timeline in Session Replay, aligned to the rest of the session's data so you can correlate a performance dip with a specific event or location.

The sensors API works the same across every framework integration. Which of the built-in sensors fire automatically depends on whether the active engine adapter wires up the profiler.

Recording a Custom Sensor

One call with a name and a value:

// Values can be numbers or booleans.
c3d.sensor.recordSensor("heartRate", 85);
c3d.sensor.recordSensor("playerStamina", 92.5);
c3d.sensor.recordSensor("isMoving", true);

The name is a string of your choosing — it becomes the sensor's identifier on the dashboard. Use stable names across sessions so the dashboard aggregates them correctly.

Recording at a Fixed Interval

For data that doesn't change every frame — biometrics, periodic state checks — a simple setInterval is enough:

setInterval(() => {
    const currentHeartRate = getHeartRateFromDevice();
    c3d.sensor.recordSensor("heartRate", currentHeartRate);

    const activeEnemies = enemyManager.getActiveCount();
    c3d.sensor.recordSensor("activeEnemies", activeEnemies);
}, 1000);

Recording too frequently burns bandwidth without adding insight; once a second is a reasonable default for slow-moving values.

Standard (Automatic) Sensors

When the session starts, the SDK wires up a set of built-in sensors. Most of them depend on engine information and are only populated when you've passed a renderer/application to the SDK or started the session with a valid XRSession.

Framerate (FPSTracker)

Always on while a session is active.

  • Average FPS — rolling average frames per second over a one-second window. In WebXR sessions it uses the XR frame timing provided by the runtime, which is the most accurate reading available.
  • 1% Low FPS — framerate during the worst-performing slice of the window, useful for catching stuttering that an average hides.

HMD Orientation (HMDOrientationTracker)

Recorded whenever an XRSession is active.

  • HMD Pitch — vertical tilt of the headset, in degrees.
  • HMD Yaw — horizontal rotation of the headset, in degrees.

Controllers (ControllerTracker)

Recorded whenever the XR input sources include tracked controllers.

  • Controller height from HMD — vertical distance of the left or right controller relative to the headset. Useful for analyzing hand posture and gestures.

Boundary (BoundaryTracker)

Recorded when the XR session was requested with bounded-floor.

  • RoomSize — the area (in m²) of the participant's defined physical play space.

Engine Profiler (Profiler)

Only recorded when you pass a renderer or application instance into the C3D constructor. Works with Three.js (new C3D(settings, renderer)) and PlayCanvas (new C3D(settings, app)).

  • Draw Calls Count — number of render commands issued per frame.
  • System Memory In MB — total memory used by the application.
  • Main Thread Time In Ms — time the main thread spent producing the last frame.

Engine support for automatic sensors

The profiler specifically is Three.js / PlayCanvas. Framerate, HMD orientation, controllers, and boundary work across every adapter (they only need the XRSession, which every integration passes to startSession).

Configuration and Batching

Sensor readings are queued locally and sent to the server in batches:

// settings.js
export default {
  config: {
    // ... other settings
    sensorDataLimit: 512, // default
  },
};
// At runtime
c3d.config("sensorDataLimit", 32);

c3d.endSession() flushes any queued sensor readings, and c3d.setScene(...) flushes them so readings stay attributed to the scene they were recorded in.

intercom If you have a question or any feedback about our documentation please use the Intercom button (purple circle) in the lower right corner of any web page or join our Discord.