Collision System

Contacts

Reads ENTER, STAY, and EXIT events produced by the physics simulation.

Native contact callbacks are copied into a bounded thread-safe queue. jolt_update() drains that queue into a world event list and into per-body lists for the most recently processed frame.

Event constants#

ConstantValueMeaning
JOLT_COLLISION_ENTER1A body/sub-shape pair started touching
JOLT_COLLISION_STAY2The pair persisted during a simulation step
JOLT_COLLISION_EXIT3The active pair stopped touching

High-Level API#

GML
var world_events = jolt_get_collisions();
var body_events = body.get_collisions();
var dropped = jolt_get_dropped_collision_count();

World event fields#

FieldDescription
typeENTER, STAY, or EXIT constant
body_a / body_bManaged JoltBody values when still known
body_a_handle / body_b_handleRaw generational handles
body_a_valid / body_b_validWhether the high-level body lookup succeeded
positionWorld-space midpoint of the first available manifold point pair
normalWorld-space native manifold normal in body_a/body_b order
penetration_depthNative manifold penetration; EXIT is forced to 0
body_a_sensor / body_b_sensorSeparate sensor flags
user_data_a / user_data_bCurrent GML user_data or undefined

Per-body event fields#

FieldDescription
typeENTER, STAY, or EXIT
bodyThe JoltBody whose list is being read
other_bodyOther managed JoltBody, when valid
entity / other_entityGML user_data values
other_handle / other_validRaw handle and lookup state
position / normal / penetration_depthContact geometry
sensorTrue when either body is a sensor

For body_b, the wrapper negates the native normal so each body's list has the opposite orientation. A world event retains the native body_a/body_b ordering.

Queue behaviour and limits#

  • The native queue holds at most 4096 events.
  • When full, the oldest event is removed and the dropped counter increases.
  • The active-contact map is keyed by both BodyIDs and both SubShapeIDs, so compounds can produce distinct sub-shape pairs.
  • EXIT reuses the last stored contact position and normal and sets penetration_depth to 0.
  • Only the first available manifold point pair is exposed by the public event.

Typical loop#

GML
var events = jolt_get_collisions();
for (var i = 0; i < array_length(events); ++i) {
    var event = events[i];
    switch (event.type) {
        case JOLT_COLLISION_ENTER: break;
        case JOLT_COLLISION_STAY:  break;
        case JOLT_COLLISION_EXIT:  break;
    }
}

Low-Level / Advanced API#

GML
jolt_world_collision_next(world)
jolt_world_collision_get_dropped_count(world)
jolt_world_collision_clear(world)

collision_next() pops one copied event and returns undefined when empty. collision_clear() removes queued events and resets the dropped counter; the managed runtime normally drains automatically.

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 / ownerSignatureOperation contract
jolt_get_collisionsjolt_get_collisions()Managed events from latest drain after jolt_update / dropped-event count. Read after update; not a query for all current overlaps.
jolt_get_dropped_collision_countjolt_get_dropped_collision_count()Managed events from latest drain after jolt_update / dropped-event count. Read after update; not a query for all current overlaps.
jolt_layer_set_collisionjolt_layer_set_collision(layer_a, layer_b, enabled)Two live same-world layers + enabled → Boolean. Sets pair collision matrix, not a query mask.
JoltBody.get_collisionsJoltBody.get_collisions()Managed event array from the latest jolt_update; not a persistent overlap list.