jolt_update
Advances the managed world with a fixed timestep and bounded catch-up.
jolt_update() converts frame time into zero or more fixed simulation steps. The accumulator makes simulation timing independent of render-frame timing, while max_frame_time and max_steps prevent an unbounded catch-up spiral.
Syntax#
jolt_update([dt]);| Argument | Type | Description |
|---|---|---|
| dt | Real | undefined | OPTIONAL. Frame duration in seconds. Defaults to undefined, using delta_time / 1,000,000. |
Returns#
Real. Number of fixed steps processed, including 0. -1 indicates an invalid operation or simulation failure; read jolt_get_error() immediately.
Typical Step event#
// Step event of the physics controller.
var steps = jolt_update();
if (steps < 0) {
show_debug_message(jolt_get_error().message);
}
// Physics transforms and current-frame contacts are now ready.
player_body.sync();
var contacts = jolt_get_collisions();Frame time input#
| Call | Time source |
|---|---|
| jolt_update() | GameMaker delta_time converted from microseconds to seconds. |
| jolt_update(seconds) | Explicit non-negative number of seconds. |
| Any negative argument | Selects automatic delta_time behaviour. |
Fixed-step algorithm#
- The supplied frame time is clamped to max_frame_time before being added to the accumulator.
- While the accumulator contains at least fixed_dt, the world advances by exactly fixed_dt.
- At most max_steps are performed in one call.
- Each successful step subtracts fixed_dt and increments the lifetime simulation-step counter.
- If max_steps is reached with more full steps pending, excess backlog is discarded while the fractional remainder is retained.
- Contacts and character contacts are drained after stepping, including calls that perform zero steps.
Default timing#
| Setting | Default | Effect |
|---|---|---|
| fixed_dt | 1 / 60 s | 60 physics steps per simulated second. |
| max_frame_time | 0.25 s | At most a quarter-second enters the accumulator per update. |
| max_steps | 8 | At most eight fixed steps are processed per call. |
Catch-up example#
// With fixed_dt = 1/60 and an explicit 0.05 second frame:
var steps = jolt_update(0.05);
// Normally processes 3 fixed steps, subject to accumulated remainder.Per-step processing#
Before each world step the high-level character state is prepared. The native world advances CharacterVirtual controllers and then calls the Jolt rigid-body update. Afterwards the wrapper updates managed character state. Once all steps finish, collision queues are mapped to world and per-body event arrays.
Reading current state#
var total_steps = jolt_get_simulation_steps();
var fixed_seconds = jolt_fixed_timestep();
var world_events = jolt_get_collisions();
var dropped = jolt_get_dropped_collision_count();Read transforms, sync bound instances, and consume contact arrays after jolt_update(). Per-body and world collision lists represent the latest drain and are replaced by a later update.
Collision substeps#
The low-level convenience jolt_step() chooses collision_steps as ceil(delta_time × 60), clamped from 1 to 64. With the default fixed_dt of 1/60 this is one collision step per fixed update.
Low-Level / Advanced API#
jolt_step(world, delta_time)
jolt_world_step(world, delta_time, collision_steps=1)Low-level stepping requires a live world, finite delta_time greater than 0, and collision_steps from 1 through 64. It does not provide the managed accumulator, frame clamp, catch-up limit, high-level error context, or automatic collision-array mapping.
Verified operation contracts#
These contracts distinguish units, return values, errors and lifetime according to the current implementation. Check results: false, 0 and undefined can mean different things for different methods.
| Symbol / owner | Signature | Operation contract |
|---|---|---|
| jolt_fixed_timestep | jolt_fixed_timestep() | Reads managed state without stepping: started Boolean / world handle / fixed_dt s / cumulative step count / valid body-wrapper count. Wrapper count is not a validation of every native handle. |
| jolt_get_simulation_steps | jolt_get_simulation_steps() | Reads managed state without stepping: started Boolean / world handle / fixed_dt s / cumulative step count / valid body-wrapper count. Wrapper count is not a validation of every native handle. |
| jolt_is_started | jolt_is_started() | Reads managed state without stepping: started Boolean / world handle / fixed_dt s / cumulative step count / valid body-wrapper count. Wrapper count is not a validation of every native handle. |
| jolt_update | jolt_update(frame_seconds = -1.0) | Returns completed fixed-step count, -1 on error. Omitted/negative argument uses delta_time microseconds → seconds; caps input with max_frame_time/max_steps, drops excess backlog. Call once per frame; includes managed pre/post systems and contact draining. |