Box3D 0.1.0
A 3D physics engine for games
Loading...
Searching...
No Matches

Record and replay world state for debugging. More...

Collaboration diagram for Recording:

Data Structures

struct  b3RecPlayerInfo
 Summary of a recording, read once at open so a viewer can frame and label it. More...
struct  b3RecQueryInfo
 A spatial query recorded during a replayed frame, exposed for inspection. More...
struct  b3RecQueryHit
 One result of a recorded spatial query. More...

Typedefs

typedef struct b3Recording b3Recording
 Opaque recording handle. Create with b3CreateRecording, destroy with b3DestroyRecording.
typedef struct b3RecPlayer b3RecPlayer
 Opaque incremental replay player with a keyframe ring for O(interval) backward seek.

Enumerations

enum  b3RecQueryType {
  b3_recQueryOverlapAABB , b3_recQueryOverlapShape , b3_recQueryCastRay , b3_recQueryCastShape ,
  b3_recQueryCastRayClosest , b3_recQueryCastMover , b3_recQueryCollideMover
}
 The kind of a recorded spatial query, matching the public query and cast functions.

Functions

b3Recordingb3CreateRecording (int byteCapacity)
 Create a recording buffer with an optional initial byte capacity.
void b3DestroyRecording (b3Recording *recording)
 Destroy a recording and free its buffer.
const uint8_t * b3Recording_GetData (const b3Recording *recording)
 Get a pointer to the raw recording bytes.
int b3Recording_GetSize (const b3Recording *recording)
 Get the number of bytes currently in the recording buffer.
void b3World_StartRecording (b3WorldId worldId, b3Recording *recording)
 Begin recording world mutations into the provided buffer.
void b3World_StopRecording (b3WorldId worldId)
 End the current recording session.
bool b3SaveRecordingToFile (const b3Recording *recording, const char *path)
 Save the recording buffer to a file.
b3Recordingb3LoadRecordingFromFile (const char *path)
 Load a recording from a file.
bool b3ValidateReplay (const void *data, int size, int workerCount)
 Replay a recording from memory and verify it reproduces the same world-state hashes.
b3RecPlayerb3RecPlayer_Create (const void *data, int size, int workerCount)
 Create a player over a recording.
void b3RecPlayer_Destroy (b3RecPlayer *player)
 Destroy the player and free all memory. Restores the previous global length scale.
bool b3RecPlayer_StepFrame (b3RecPlayer *player)
 Advance one frame: dispatch ops until the next Step completes.
void b3RecPlayer_Restart (b3RecPlayer *player)
 Rewind to frame 0 (in-place restore so the world id stays stable).
void b3RecPlayer_SeekFrame (b3RecPlayer *player, int targetFrame)
 Seek to a specific frame.
b3WorldId b3RecPlayer_GetWorldId (const b3RecPlayer *player)
int b3RecPlayer_GetFrame (const b3RecPlayer *player)
int b3RecPlayer_GetFrameCount (const b3RecPlayer *player)
bool b3RecPlayer_IsAtEnd (const b3RecPlayer *player)
bool b3RecPlayer_HasDiverged (const b3RecPlayer *player)
b3RecPlayerInfo b3RecPlayer_GetInfo (const b3RecPlayer *player)
int b3RecPlayer_GetDivergeFrame (const b3RecPlayer *player)
void b3RecPlayer_SetWorkerCount (b3RecPlayer *player, int count)
 Set the worker count of the replay world.
void b3RecPlayer_SetKeyframePolicy (b3RecPlayer *player, size_t budgetBytes, int minIntervalFrames)
 Tune the keyframe ring used to speed up backward seeking.
size_t b3RecPlayer_GetKeyframeBudget (const b3RecPlayer *player)
int b3RecPlayer_GetKeyframeMinInterval (const b3RecPlayer *player)
int b3RecPlayer_GetKeyframeInterval (const b3RecPlayer *player)
size_t b3RecPlayer_GetKeyframeBytes (const b3RecPlayer *player)
int b3RecPlayer_GetBodyCount (const b3RecPlayer *player)
b3BodyId b3RecPlayer_GetBodyId (const b3RecPlayer *player, int index)
 Resolve a creation ordinal to the live body id at the current frame.
void b3RecPlayer_SetDebugShapeCallbacks (b3RecPlayer *player, b3CreateDebugShapeCallback *createDebugShape, b3DestroyDebugShapeCallback *destroyDebugShape, void *context)
 Wire host debug-shape callbacks into the player's replay world so a renderer can build per-shape draw resources (the 3D sample needs this or the replay world draws nothing).
void b3RecPlayer_DrawFrameQueries (b3RecPlayer *player, b3DebugDraw *draw, int queryIndex, int selectedIndex)
 Draw the spatial queries recorded during the most recently replayed frame, layered on top of the world.
int b3RecPlayer_GetFrameQueryCount (const b3RecPlayer *player)
b3RecQueryInfo b3RecPlayer_GetFrameQuery (const b3RecPlayer *player, int index)
 Get a recorded query from the most recently replayed frame by index.
b3RecQueryHit b3RecPlayer_GetFrameQueryHit (const b3RecPlayer *player, int queryIndex, int hitIndex)
 Get one result of a recorded query from the most recently replayed frame.

Detailed Description

Record and replay world state for debugging.


Data Structure Documentation

◆ b3RecPlayerInfo

struct b3RecPlayerInfo

Summary of a recording, read once at open so a viewer can frame and label it.

Collaboration diagram for b3RecPlayerInfo:
Data Fields
b3AABB bounds
int frameCount
float lengthScale
int subStepCount
float timeStep
int workerCount

◆ b3RecQueryInfo

struct b3RecQueryInfo

A spatial query recorded during a replayed frame, exposed for inspection.

Collaboration diagram for b3RecQueryInfo:
Data Fields
b3AABB aabb
b3QueryFilter filter
int hitCount
uint64_t id
uint64_t key
const char * name
b3Pos origin
b3Vec3 translation
b3RecQueryType type

◆ b3RecQueryHit

struct b3RecQueryHit

One result of a recorded spatial query.

Collaboration diagram for b3RecQueryHit:
Data Fields
float fraction
b3Vec3 normal
b3Pos point
b3ShapeId shape

Function Documentation

◆ b3CreateRecording()

b3Recording * b3CreateRecording ( int byteCapacity)

Create a recording buffer with an optional initial byte capacity.

Pass 0 to use the default (64 KiB). The buffer grows on demand.

Returns
a new recording, owned by the caller

◆ b3DestroyRecording()

void b3DestroyRecording ( b3Recording * recording)

Destroy a recording and free its buffer.

Parameters
recordingmay be NULL

◆ b3LoadRecordingFromFile()

b3Recording * b3LoadRecordingFromFile ( const char * path)

Load a recording from a file.

Returns NULL on failure (file not found, wrong magic). The caller owns the returned recording and must destroy it with b3DestroyRecording.

Parameters
pathfile path to read

◆ b3Recording_GetData()

const uint8_t * b3Recording_GetData ( const b3Recording * recording)

Get a pointer to the raw recording bytes.

Valid until the recording buffer is modified or destroyed.

Parameters
recordingthe recording handle
Returns
pointer to the byte buffer, or NULL if no bytes have been written

◆ b3Recording_GetSize()

int b3Recording_GetSize ( const b3Recording * recording)

Get the number of bytes currently in the recording buffer.

Parameters
recordingthe recording handle

◆ b3RecPlayer_Create()

b3RecPlayer * b3RecPlayer_Create ( const void * data,
int size,
int workerCount )

Create a player over a recording.

Owns a private copy of the bytes.

Parameters
datapointer to recording bytes
sizebyte count of the recording
workerCountworker count for the replay world; pass 1 to match a serial recording. Replaying at a different count re-partitions the constraint graph, so the StateHash check becomes a cross-thread determinism test. Adjustable later with b3RecPlayer_SetWorkerCount.
Returns
a new player, or NULL on bad header or deserialization failure

◆ b3RecPlayer_DrawFrameQueries()

void b3RecPlayer_DrawFrameQueries ( b3RecPlayer * player,
b3DebugDraw * draw,
int queryIndex,
int selectedIndex )

Draw the spatial queries recorded during the most recently replayed frame, layered on top of the world.

Call after b3World_Draw. NULL draw function pointers are skipped.

Parameters
playera valid player handle
drawdebug draw callbacks
queryIndexindex of the frame query to draw, or -1 to draw all of them
selectedIndexindex of the query to emphasize (reserved color plus a label), or -1 for none

◆ b3RecPlayer_GetBodyCount()

int b3RecPlayer_GetBodyCount ( const b3RecPlayer * player)
Returns
the number of bodies tracked in creation order (including holes for destroyed bodies)

◆ b3RecPlayer_GetBodyId()

b3BodyId b3RecPlayer_GetBodyId ( const b3RecPlayer * player,
int index )

Resolve a creation ordinal to the live body id at the current frame.

Returns
the body id, or a null id if that ordinal is out of range or its body is destroyed

◆ b3RecPlayer_GetDivergeFrame()

int b3RecPlayer_GetDivergeFrame ( const b3RecPlayer * player)
Returns
the first frame at which replay diverged, or -1 if it has not diverged

◆ b3RecPlayer_GetFrame()

int b3RecPlayer_GetFrame ( const b3RecPlayer * player)
Returns
the last fully-stepped frame index (0 before any step)

◆ b3RecPlayer_GetFrameCount()

int b3RecPlayer_GetFrameCount ( const b3RecPlayer * player)
Returns
total number of recorded frames

◆ b3RecPlayer_GetFrameQueryCount()

int b3RecPlayer_GetFrameQueryCount ( const b3RecPlayer * player)
Returns
the number of spatial queries recorded for the most recently replayed frame

◆ b3RecPlayer_GetInfo()

b3RecPlayerInfo b3RecPlayer_GetInfo ( const b3RecPlayer * player)
Returns
a summary of the recording read at open: frame count, recorded tuning, and bounds

◆ b3RecPlayer_GetKeyframeBudget()

size_t b3RecPlayer_GetKeyframeBudget ( const b3RecPlayer * player)
Returns
the keyframe memory budget in bytes

◆ b3RecPlayer_GetKeyframeBytes()

size_t b3RecPlayer_GetKeyframeBytes ( const b3RecPlayer * player)
Returns
the memory currently held by keyframe snapshots, in bytes

◆ b3RecPlayer_GetKeyframeInterval()

int b3RecPlayer_GetKeyframeInterval ( const b3RecPlayer * player)
Returns
the current keyframe spacing in frames; starts at the min interval and doubles as the ring evicts to stay under budget, so it reflects the effective backward-seek granularity now

◆ b3RecPlayer_GetKeyframeMinInterval()

int b3RecPlayer_GetKeyframeMinInterval ( const b3RecPlayer * player)
Returns
the finest keyframe spacing in frames

◆ b3RecPlayer_GetWorldId()

b3WorldId b3RecPlayer_GetWorldId ( const b3RecPlayer * player)
Returns
the world currently driven by this player

◆ b3RecPlayer_HasDiverged()

bool b3RecPlayer_HasDiverged ( const b3RecPlayer * player)
Returns
true when any StateHash mismatch has been detected

◆ b3RecPlayer_IsAtEnd()

bool b3RecPlayer_IsAtEnd ( const b3RecPlayer * player)
Returns
true when the op stream is exhausted

◆ b3RecPlayer_SeekFrame()

void b3RecPlayer_SeekFrame ( b3RecPlayer * player,
int targetFrame )

Seek to a specific frame.

Forward seek steps op-by-op; backward seek restores the nearest keyframe then re-steps the remaining gap.

◆ b3RecPlayer_SetDebugShapeCallbacks()

void b3RecPlayer_SetDebugShapeCallbacks ( b3RecPlayer * player,
b3CreateDebugShapeCallback * createDebugShape,
b3DestroyDebugShapeCallback * destroyDebugShape,
void * context )

Wire host debug-shape callbacks into the player's replay world so a renderer can build per-shape draw resources (the 3D sample needs this or the replay world draws nothing).

Rebuilds the current world under the new callbacks and rewinds to frame 0, so call it once right after b3RecPlayer_Create and re-read the world id afterward. The callbacks persist across Restart and backward seeks, which recreate the world internally.

Parameters
playerthe player to configure
createDebugShapecalled when a replayed shape is added; returns a user draw handle
destroyDebugShapecalled when a replayed shape is removed; may be NULL
contextuser context passed to both callbacks

◆ b3RecPlayer_SetKeyframePolicy()

void b3RecPlayer_SetKeyframePolicy ( b3RecPlayer * player,
size_t budgetBytes,
int minIntervalFrames )

Tune the keyframe ring used to speed up backward seeking.

A keyframe is a periodic snapshot the player restores from instead of replaying from the start, trading memory for seek speed.

Parameters
playerthe recording player
budgetBytesmemory cap for the kept snapshots; the spacing widens to stay under it
minIntervalFramesfinest spacing between keyframes, in frames A zero budget or a non-positive interval keeps that value. Clears the existing ring, so call b3RecPlayer_Restart afterward to repopulate it under the new policy.

◆ b3RecPlayer_SetWorkerCount()

void b3RecPlayer_SetWorkerCount ( b3RecPlayer * player,
int count )

Set the worker count of the replay world.

Clamped to [1, B3_MAX_WORKERS]. Applied to the live world at once and reused whenever the player rebuilds its world on Restart or a backward seek. Replaying at a different count than recorded re-partitions the constraint graph, so the StateHash check becomes a cross-thread determinism test.

◆ b3RecPlayer_StepFrame()

bool b3RecPlayer_StepFrame ( b3RecPlayer * player)

Advance one frame: dispatch ops until the next Step completes.

Returns
true when a frame was stepped, false at end-of-recording

◆ b3SaveRecordingToFile()

bool b3SaveRecordingToFile ( const b3Recording * recording,
const char * path )

Save the recording buffer to a file.

Returns true on success.

Parameters
recordingthe recording to save
pathfile path to write

◆ b3ValidateReplay()

bool b3ValidateReplay ( const void * data,
int size,
int workerCount )

Replay a recording from memory and verify it reproduces the same world-state hashes.

Stands up a fresh world, restores the seed snapshot, replays every op, and checks each embedded StateHash record. Returns true if replay completed without id mismatches or hash divergences.

Parameters
datapointer to recording bytes
sizebyte count of the recording
workerCountreserved for future multithreaded replay; pass 1 for now

◆ b3World_StartRecording()

void b3World_StartRecording ( b3WorldId worldId,
b3Recording * recording )

Begin recording world mutations into the provided buffer.

The buffer is reset on each call so a single b3Recording can be reused for multiple sessions.

Parameters
worldIdthe world to record
recordingthe recording handle to write into

◆ b3World_StopRecording()

void b3World_StopRecording ( b3WorldId worldId)

End the current recording session.

Writes the trailing geometry registry and backpatches the header. The buffer remains valid until the recording is destroyed.

Parameters
worldIdthe world currently being recorded