Custom Events
Custom Events are timestamped, positioned markers you record from anywhere in your application. They are the primary way the SDK captures interactions — things the participant did, milestones they reached, or states your app wants to remember. Each event appears as a point on the session timeline in Session Replay, pinned at the 3D position you supplied.
This page covers the Custom Events API and the events the SDK records for you automatically. The API is the same across every framework integration.
Sending a Custom Event
At its simplest, an event has a name and a 3D position:
// [x, y, z] in world space
const eventPosition = [1.5, 1.2, -3.0];
c3d.customEvent.send("player_jumped", eventPosition);
Adding Properties
An optional third argument lets you attach arbitrary contextual data. Property values can be strings, numbers, or booleans — the same filterable keys you'll use on the dashboard.
const eventPosition = [10.2, 0.4, 8.1];
c3d.customEvent.send("enemy_hit", eventPosition, {
weapon_used: "Plasma Rifle",
target_type: "EnemyDrone",
damage_dealt: 75,
was_critical_hit: true,
});
Use properties aggressively. Dashboards can filter, group, and compare on property keys after the fact — enemy_hit with a weapon_used property is far more useful than a separate event per weapon.
Picking a Position
The position should reflect where the event occurred in world space. Common patterns:
- A participant action: the headset or hand's world position.
- A world event (a door opening, an enemy spawning): that object's world position.
- A UI event with no natural position:
[0, 0, 0]is fine; the dashboard will still show it on the timeline.
Standard (Automatic) Events
The SDK sends a handful of events on its own so you don't have to wire them up. These appear in every session:
- Session start — fired when
c3d.startSession(...)succeeds. Marks the start of data collection. - Session end — fired when
c3d.endSession()is called. Includes asessionlengthproperty (seconds) and aReasonproperty. - Left Controller Lost tracking / Right Controller Lost tracking — fired when the XR runtime reports that the corresponding controller has dropped tracking.
- Left Controller regained tracking / Right Controller regained tracking — fired when tracking is restored.
- User Changed Boundary — fired when the participant modifies their configured room boundary. Only fires when the session was requested with
bounded-floor. - User Exited Boundary — fired when the HMD leaves the bounded play area. Also requires
bounded-floor. - Input Tracking Changed — fired when the primary WebXR input source changes (for example, hands to controllers).
Configuration and Batching
Custom Events are queued locally and sent to the server in batches. You can tune the batch size at init time or at runtime:
// settings.js
export default {
config: {
// ... other settings
customEventBatchSize: 256, // default
},
};
// At runtime
c3d.config("customEventBatchSize", 32);
c3d.endSession() flushes any queued events regardless of batch size, and c3d.setScene(...) flushes them so events stay attributed to the scene they came from.
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.