‹›
Utility Scripts

Physical Scale

Creates a real physics load-cell platform and measures the load carried by its fixed support.

jolt_scale_create creates an owned Dynamic box platform and fixes it to the world with an internal Fixed Constraint. After each completed physics step, the helper reads the constraint's solved linear reaction impulse, projects it onto a chosen load axis and divides by the fixed timestep to obtain force. It is not an overlap query and it does not add the masses of touching bodies.

Physical principle#

GML
objects and applied forces
        ↓
Dynamic box platform
        ↓
Fixed Constraint reaction
        ↓
force along load direction
  • The platform is Dynamic so ordinary Jolt contacts and friction can transfer forces into it.
  • The internal Fixed Constraint holds the platform at its creation pose and carries the applied load into the fixed world.
  • The solver's accumulated linear impulse is divided by physics-step time, producing force in newtons when the project uses consistent metre-kilogram-second units.
  • Only the non-negative component along direction is reported. A force acting against the selected positive load axis is clamped to zero.
  • The platform's own theoretical gravity load is subtracted automatically, so a newly created empty scale begins close to zero.

Syntax#

Syntax
scale = jolt_scale_create(-6.5, -3.1, 0.3, 3.0, 1.8, 0.05);
scale.set_smoothing(0.2);
scale.set_enabled(true);
scale.set_direction(0, 0, 1);

Arguments#

ArgumentDescription
x, y, zFinite world-space centre of the box platform.
widthFull positive size along public X.
depthFull positive size along public Y.
heightFull positive size along public Z.
optionsOptional scale settings plus supported normal JoltBody creation options.

Scale options#

FieldDefaultMeaning
mass20.0Positive mass of the owned platform itself. Its theoretical gravity reaction becomes the initial empty baseline.
reference_gravity9.81Positive divisor used only to convert measured force into equivalent kilograms.
direction{x:0,y:0,z:1}Finite non-zero local load axis. It is normalized automatically.
smoothing0.15Non-negative exponential smoothing time constant in physics seconds. Zero uses raw readings.
enabledtrueEnables measurement. It does not enable or disable the physical platform or constraint.

Useful body options#

FieldUse on a scale
friction / restitutionControl how loads contact, slide and bounce on the platform.
layerPlaces the platform in the required collision layer.
dataStores project metadata on scale.body.
massAlso passes through normal body options, but should normally remain the creation-time platform mass.
allow_sleepingAccepted during option application but deliberately overridden to false so readings remain fresh.

Creation example#

GML
scale = jolt_scale_create(-6.5, -3.1, 0.3, 3.0, 1.8, 0.05);
scale.set_smoothing(0.2);
scale.set_enabled(true);
scale.set_direction(0, 0, 1);

Reading the scale#

GML
// Call jolt_update() first so a completed physics step exists.
jolt_update(delta_time / 1000000);

if (scale.is_valid()) {
    var kilograms = scale.get_weight();
    var force_newtons = scale.get_force();

    if (!jolt_has_error()) {
        draw_text(32, 32, string_format(kilograms, 0, 2) + " kg");
        draw_text(32, 52, string_format(force_newtons, 0, 1) + " N");
    }
}
  • Readings update only after a successfully completed physics step. Repeated getters in the same step return the same sample.
  • get_force() and get_weight() return smoothed values suitable for UI.
  • get_raw_force() and get_raw_weight() return the latest unsmoothed physics-step sample for diagnostics or impact logic.
  • Getter failure returns a safe numeric zero and records a normal high-level error; do not treat zero as proof that an invalid scale is unloaded.

Public methods#

MethodPurpose
is_valid()Checks the managed wrapper, owned platform and native scale resource.
get_native_handle()Returns the opaque scale handle, or 0 when invalid.
get_body() / bodyReturns the normal managed JoltBody owned by the scale.
get_force()Exponentially smoothed reaction along the load axis in newtons.
get_raw_force()Latest unsmoothed reaction along the load axis in newtons.
get_weight()Smoothed force divided by reference_gravity.
get_raw_weight()Raw force divided by reference_gravity.
tare()Stores the current total reaction as the new zero and immediately clears both displayed readings.
set_smoothing(seconds) / get_smoothing()Changes or reads the exponential low-pass time constant. Zero disables smoothing.
set_enabled(bool) / get_enabled()Enables or disables measurement without removing physical support.
set_direction(x,y,z) / get_direction()Changes or reads the normalized local load axis and resets the current readings.
destroy()Destroys the scale, its internal constraint and its owned platform. Repeated calls are safe.

Tare and containers#

GML
// Place the empty container on the platform and wait until it settles.
if (keyboard_check_pressed(ord("T"))) {
    if (!scale.tare()) {
        show_debug_message(jolt_get_error().message);
    }
}
  • A newly created scale subtracts only the owned platform's theoretical gravity load.
  • tare() replaces that baseline with the complete reaction measured at the time of the call, which is useful for containers and fixtures.
  • Call tare only after the load has settled. Taring during an impact or acceleration makes that transient force the new zero.
  • Changing direction recalculates the theoretical platform baseline and clears raw and smoothed readings; tare again when a container should remain excluded.

Smoothing#

  • Smoothing is an exponential low-pass filter measured in elapsed physics time, so render framerate does not change its response.
  • A larger time constant produces a steadier but slower display. Values around 0.1 to 0.3 seconds are a practical UI starting point.
  • Zero makes the smoothed reading immediately equal to the latest raw sample.
  • Use raw force to inspect short impact peaks; use smoothed weight for readable labels and dashboards.

Load direction#

  • The default {0,0,1} measures upward support reaction on a normal horizontal platform.
  • The vector is stored in the platform's fixed local reference frame and normalized by the native implementation.
  • Only the positive projected reaction is reported. Choose the sign so the expected support force points along the axis.
  • get_weight() still divides by reference_gravity for horizontal or angled axes, so its kg value remains force-equivalent rather than object mass.

Ownership and lifecycle#

  • The scale owns its Dynamic platform and internal Fixed Constraint.
  • scale.destroy() invalidates scale.body and removes both native resources.
  • Manually destroying scale.body atomically invalidates the scale and removes its internal constraint.
  • The platform has sleeping disabled so the solver produces a fresh constraint reaction even after a load stands still for a long time.
  • jolt_stop() cleans up live scales as part of managed world teardown.
  • Use scale.body for normal data, layer, friction, debug drawing and visual-transform access, but do not destroy it separately unless the entire scale should be removed.

Physical interpretation and limitations#

  • A stack contributes through the forces actually transmitted to the platform; upper bodies do not need direct contact with it.
  • When an object is supported by two platforms, each scale reports only its share of the reaction.
  • Ropes, springs, constraints and applied forces contribute according to the load they transmit through the platform.
  • Impacts create temporary peaks that can exceed static weight.
  • Solver settling, contact softness, friction and fixed timestep produce small fluctuations; they are expected physics behaviour.
  • The scale measures one signed axis and clamps negative reaction. It is not a six-axis force/torque sensor.

Validation and errors#

  • Call jolt_start() before jolt_scale().
  • Position and dimensions must be finite; every dimension must be greater than zero.
  • mass and reference_gravity must be finite and positive.
  • smoothing must be finite and non-negative; enabled must be Boolean.
  • direction must be a struct with finite x, y and z forming a non-zero vector.
  • Creation returns undefined on failure. Mutating methods return false; numeric getters return 0 and get_direction() returns undefined when an error occurs.
  • Read jolt_get_error() immediately after a failed managed call before another Jolt operation replaces it.

Low-Level / Advanced API#

GML
jolt_world_scale_create(world, x, y, z, width, depth, height, mass, reference_gravity)
jolt_world_scale_destroy(world, scale_handle)
jolt_world_scale_is_valid(world, scale_handle)
jolt_world_scale_get(world, scale_handle, property)
jolt_world_scale_tare(world, scale_handle)
jolt_world_scale_set_smoothing(world, scale_handle, seconds)
jolt_world_scale_set_enabled(world, scale_handle, enabled)
jolt_world_scale_set_direction(world, scale_handle, x, y, z)

Legacy / Deprecated API#

jolt_scale(x,y,z,width,depth,height,options) remains a compatibility factory sharing the same implementation. Use this path for creation-only reference_gravity. New factory defaults: mass=20 kg, reference_gravity=9.81 m/s², smoothing=0.15 s, enabled=true, direction={x:0,y:0,z:1}. Ordinary body parameters follow the unchanged creation path.

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
JoltScale.get_bodyJoltScale.get_body()Returns the owned JoltBody platform, otherwise undefined. Destroying it invalidates the scale; Scale.destroy also destroys the platform.
JoltScale.get_directionJoltScale.get_direction()Normalized platform-local vector {x, y, z}, default {0, 0, 1}; undefined if any component read fails.
JoltScale.get_enabledJoltScale.get_enabled()Boolean; compares the native value with 1. False on error; inspect the error state to distinguish it. Default true.
JoltScale.get_native_handleJoltScale.get_native_handle()Live native handle, otherwise 0; do not retain it across destroy or a world restart.
JoltScale.get_raw_forceJoltScale.get_raw_force()Unsmoothed load-axis reaction from the latest physics step; unit N. On error returns 0 and records an error; zero alone does not establish validity.
JoltScale.get_raw_weightJoltScale.get_raw_weight()Unsmoothed equivalent mass, force divided by reference gravity; unit kg. On error returns 0 and records an error; zero alone does not establish validity.
JoltScale.get_smoothingJoltScale.get_smoothing()Smoothing time, default 0.15 s; unit s. On error returns 0 and records an error; zero alone does not establish validity.
JoltScale.is_validJoltScale.is_valid()Boolean; checks both the platform and native scale. An invalid platform invalidates the scale.

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_scalejolt_scale(x, y, z, width, depth, height, options = undefined)