Utility Scripts

Explosions

One-shot impulse for Dynamic rigid bodies, optionally Characters and local Soft Body vertices.

One-shot jolt_explosion applies immediately. A configured emitter applies only when explode() is called.

Syntax#

Syntax
jolt_explosion(x, y, z, options=undefined)

Arguments#

ArgumentTypeDescription
xRealWorld-space X coordinate of the explosion origin.
yRealWorld-space Y coordinate of the explosion origin.
zRealWorld-space Z coordinate of the explosion origin.
optionsStruct or undefinedOptional blast strength, shape, filtering and visibility settings.

Options#

FieldDefaultDescription
radius5.0Positive world-space radius.
strength1000.0Maximum instantaneous impulse magnitude.
directionundefinedOptional non-zero {x,y,z} direction that changes the sphere into a cone.
angle90.0Full cone angle in degrees; valid range is greater than 0 and at most 360.
fallofftrueLinearly scales the impulse by 1 - distance / radius.
occlusionfalseRay-tests each eligible target against solid blocking geometry.
layersundefinedTarget JoltLayer, layer array or numeric mask; does not limit occlusion blockers.
ignoreundefinedOne live source JoltBody excluded from both overlap and occlusion queries.
include_charactersfalseBoolean; includes CharacterVirtual.
include_soft_bodiesfalseBoolean; local free-vertex response.
max_delta_velocityundefinedFinite ≥ 0 m/s; added-velocity cap, not total speed. 0 adds no velocity.

Behaviour and target rules#

  • Rigid: Distance is measured to the native center of mass. The impulse is applied at that center, wakes sleeping bodies and does not add artificial off-centre torque.
  • Rigid: With falloff disabled, every body inside the radius receives the full impulse. Strength is impulse rather than velocity, so heavier bodies accelerate less.
  • Rigid: A direction enables cone filtering. A body at exactly zero distance uses public +Z as a stable radial direction.
  • Rigid: Occlusion performs one synchronous raycast per eligible candidate. Sensors do not block it, while solid Static or Kinematic level geometry can block a target even when excluded from layers.
  • Rigid: Compound child hits are deduplicated by their owning native body handle.

Return value#

FieldTypeDescription
affected_countRealNumber of bodies that received a non-zero impulse.
bodiesArray<JoltBody>Affected managed body wrappers.
entriesArray<Struct>One {body, distance, factor, impulse} record for every affected body.
character_countRealAffected Character count.
charactersArray<JoltCharacter>Affected Characters.
character_entriesArray<Struct>Applied Character impulse records.
soft_vertex_countRealAffected vertex count.

Example#

GML
var result = jolt_explosion(x, y, z, {
    radius: 8,
    strength: 1200,
    falloff: true,
    occlusion: true,
    layers: [layer_dynamic],
    ignore: grenade_body
});

show_debug_message("Affected bodies: " + string(result.affected_count));

Current project integrations#

Targets and local response#

The rigid branch affects only live non-sensor Dynamic bodies and applies impulse at the center of mass. Character and Soft Body targets are opt-in, default false. Soft Body response is evaluated for free vertices within radius; pinned vertices stay attached. Occlusion tests affected vertices, not one ray for an entire cloth. The same falloff, cone and filters apply.

Configured emitter#

GML
explosion = jolt_explosion_create(0, 0, 0, grenade_body);
explosion.set_radius(5);
explosion.set_strength(800);
explosion.set_include_characters(true);
explosion.set_include_soft_bodies(true);
explosion.set_max_delta_velocity(10);
explosion.set_ignore(grenade_body);
var result = explosion.explode();
explosion.destroy();

With an owner Body, position/rotation are local; without one they are world-space. Setters return Boolean; get_transform returns a transform or undefined and explode returns a result struct even on error (empty). destroy, owner destruction or jolt_stop invalidate it. explode can be repeated while valid. set_layers accepts a live layer or layer array; one-shot options.layers additionally support a numeric mask.

Asset workflow#

GML
explosion = jolt_asset_create_explosion(asset, "explosion", grenade_body);
if (!is_undefined(explosion)) {
    explosion.set_include_characters(true);
    explosion.set_include_soft_bodies(true);
    explosion.explode();
}

The last argument is a live created Body, not a loaded asset. Creating the body does not automatically trigger an explosion. Parameters forward to the same central function. Public names are include_characters/include_soft_bodies; affect_* are not current names.

Emitter API#

MethodContract
ExplosionEmitter.set_radius(value)Real > 0 m; default 5; max sqrt(FLT_MAX)/4.
ExplosionEmitter.set_strength(value)Real > 0 N·s; default 1000; finite float.
ExplosionEmitter.set_position(x,y,z)Real x/y/z; finite float; local with owner / world without owner.
ExplosionEmitter.set_rotation(x,y,z,w)Unit XYZW quaternion; abs(length²−1) ≤ 0.00001; normalized on success; identity default.
ExplosionEmitter.set_rotation_euler(x,y,z)Finite Euler degrees; converted to quaternion.
ExplosionEmitter.set_direction(x,y,z)Finite nonzero vector; normalized; enables directional=true; initial direction +Z.
ExplosionEmitter.set_directional(value)Boolean; default false.
ExplosionEmitter.set_angle(value)Real full cone angle (0,360] degrees; default 90.
ExplosionEmitter.set_falloff(value)Boolean; default true.
ExplosionEmitter.set_occlusion(value)Boolean; default false.
ExplosionEmitter.set_include_characters(value) / ExplosionEmitter.set_include_soft_bodies(value)Boolean; default false.
ExplosionEmitter.set_max_delta_velocity(value)undefined = no cap; finite Real ≥ 0 m/s; default undefined.
ExplosionEmitter.set_layers(value)undefined / live JoltLayer / array of live layers in current world; copied, revalidated on explode.
ExplosionEmitter.set_ignore(body)undefined / live Body in current world; default undefined.
ExplosionEmitter.get_transform()World {position:{x,y,z},rotation:{x,y,z,w}}; undefined on invalid owner/world/range.
ExplosionEmitter.is_valid()Boolean; emitter, managed world and optional owner must remain live.
ExplosionEmitter.explode()Result struct described above, including on failure; revalidates owner, ignore and layers.
ExplosionEmitter.destroy()true; idempotently unregisters emitter; does not destroy owner Body.

Setters return true when accepting a value and false on invalid input; read jolt_get_error() immediately. Configuration applies no force. A successful setter is not an emitter-liveness test: use requires is_valid/get_transform to succeed.

Complete API declarations#

Declarations match the production GML sources. A value after = marks an optional argument. This is a signature inventory; the guide sections describe meaning, units and limitations. The type before a dot identifies the method owner, not a global function.

Symbol / ownerSignature / value
jolt_explosion_createjolt_explosion_create(x,y,z,owner=undefined)