‹›
Current project

Local force and impulse

The helper selects movable particles of one Soft Body in a world-space sphere; it does not follow the body automatically. Creation and setters apply no force. apply queues total force in newtons for the next managed update; repeated calls replace the request rather than multiplying by render FPS. A frame without a physics step keeps it pending. cancel removes it. impulse immediately applies another N·s impulse every call.

Example#

GML
push = jolt_soft_body_force(soft);
push.set_position(0, 0, 3);
push.set_direction(0, 0, -1);
push.set_radius(0.3);
push.set_strength(20);
push.set_impulse(0.5);
// Step, before the existing jolt_update():
if (mouse_check_button(mb_left)) push.apply();
if (keyboard_check_pressed(vk_space)) push.impulse();

Usage and limits#

Force is distributed with normalized smooth falloff. Pinned/attached particles are excluded. Selection is volumetric without occlusion or raycast: a tiny sphere can miss the mesh. get_affected_count updates after execution, or immediately for impulse. Queued apply requires jolt_update and is not processed by a bare custom jolt_step loop.

Radius accepts 0.001..1000 m; strength/impulse 0..1000000. set_debug(true) or JOLT_DEBUG_FORCES shows the region. destroy clears the helper and pending force, not its Soft Body. Owner destruction cleans it automatically.

API reference#

Public function and method signatures. Call methods on the returned instance; parameters with defaults are optional.

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_soft_body_forcejolt_soft_body_force(soft)Live JoltBBMODCloth/JoltBBMODSoftBody; returns a new Force or undefined, multiple helpers are allowed. Defaults: position {0, 0, 0}, direction -Z, radius 0.3 m, strength 20 N, impulse 1 N·s, debug false. Creation alone applies nothing.
JoltSoftBodyForce.applyJoltSoftBodyForce.apply()Boolean; captures current configuration before jolt_update. Latest request wins, repeats during catch-up steps, stays pending in a frame without a step, clears after a processed frame. Free particles inside radius receive normalized smoothstep force shares; pins/attachments are excluded.
JoltSoftBodyForce.cancelJoltSoftBodyForce.cancel()Boolean; removes a pending apply request, does not undo an already applied impulse/force. Requires a live helper.
JoltSoftBodyForce.destroyJoltSoftBodyForce.destroy()Boolean, repeated destruction is safe. Removes only the helper, not the soft body or rigid host. Wind disables airflow, Force cancels the pending request, Attachment releases its particle selection.
JoltSoftBodyForce.get_affected_countJoltSoftBodyForce.get_affected_count()Particle count from the last successfully submitted request, initially 0. apply updates it at a physics step; configuration alone does not refresh it.
JoltSoftBodyForce.get_debugJoltSoftBodyForce.get_debug()Stored debug Boolean; does not itself check validity.
JoltSoftBodyForce.get_directionJoltSoftBodyForce.get_direction()Copy of stored unit world {x, y, z}; configuration getter, does not itself check helper validity.
JoltSoftBodyForce.get_impulseJoltSoftBodyForce.get_impulse()Total impulse: stored number in N·s; no helper validity check.
JoltSoftBodyForce.get_positionJoltSoftBodyForce.get_position()Copy of stored world {x, y, z} in m; configuration getter without a validity check.
JoltSoftBodyForce.get_radiusJoltSoftBodyForce.get_radius()Selection radius: stored number in m; no helper validity check.
JoltSoftBodyForce.get_strengthJoltSoftBodyForce.get_strength()Total force: stored number in N; no helper validity check.
JoltSoftBodyForce.impulseJoltSoftBodyForce.impulse()Boolean; immediately applies total impulse distributed by smoothstep weights to free particles inside radius. Zero strength or an empty selection succeeds with 0 affected. Not a repeated apply.
JoltSoftBodyForce.is_validJoltSoftBodyForce.is_valid()Boolean; both helper and its soft body must be live. Destroying the soft body invalidates the helper.
JoltSoftBodyForce.set_debugJoltSoftBodyForce.set_debug(v)Boolean coercion; default false. Returns true/false, requires a live helper. Diagnostics only.
JoltSoftBodyForce.set_directionJoltSoftBodyForce.set_direction(x,y,z)Finite world x/y/z, absolute values ≤ 1e9, length ≥ 1e-6. Normalizes direction; Boolean, false for an invalid helper.
JoltSoftBodyForce.set_impulseJoltSoftBodyForce.set_impulse(v)Total impulse: finite 0..1000000 N·s, default 1; Boolean. The amount is total across the selection, not multiplied by particle count.
JoltSoftBodyForce.set_positionJoltSoftBodyForce.set_position(x,y,z)Finite world x/y/z in m, absolute values ≤ 1e9; Boolean. Changes future requests, not an already captured apply snapshot.
JoltSoftBodyForce.set_radiusJoltSoftBodyForce.set_radius(v)Selection radius: finite 0.001..1000 m, default 0.3; Boolean. The amount is total across the selection, not multiplied by particle count.
JoltSoftBodyForce.set_strengthJoltSoftBodyForce.set_strength(v)Total force: finite 0..1000000 N, default 20; Boolean. The amount is total across the selection, not multiplied by particle count.