Blender Physical Controls

Control asset API and JSON v3

Lookup, creation, JSON v3 compatibility and type-specific data contracts.

JoltPhysics Asset Editor 0.31.1 · verified against project sources on 27 September 2026.

Syntax#

Syntax
jolt_asset_get_control(asset, control_ref);
jolt_asset_create_control(asset, control_ref, body, [options]);
jolt_asset_control_settings();
Field / operationMeaning and validation
assetPlain validated data from jolt_asset_load; mutable input is checked again.
control_refExact case-sensitive Key or canonical UUID; no typo correction.
bodyExisting valid parent Body in the current world. Local mounting frame is composed with the parent origin, not COM.
optionsOptional plain struct or JoltAssetControlSettings. Only fields supported by the selected type.

Returns and errors#

jolt_asset_get_control returns an independent validated record; jolt_asset_create_control returns the existing JoltControl type. Both return undefined on failure; inspect jolt_get_error() or jolt_get_error_message() immediately. Runtime metadata includes authoring_id, authoring_key, authoring_name and authoring_configuration_id; these are distinct from runtime handles.

JSON v3#

Documents with controls[] use version:3 and format:"joltphysics-authoring". Controls are separate from shapes[]: they become independent moving bodies with constraints, not compound children. Loading allocates no mechanism, and jolt_asset_create_body creates collision shapes only. A controls-only asset may load; create its controls on an existing parent body. Assets without controls retain v1/v2 export.

All nine types share one Key namespace per root; Keys follow [a-z][a-z0-9_]{0,63}. UUIDs remain globally unique across categories. Display Name is optional. Position is [x,y,z] in metres and rotation a normalized [x,y,z,w] quaternion. The existing mirror-X conversion is already applied on export; do not repeat it in GML.

Field / operationMeaning and validation
buttonsize:[x,y,z], travel, initial_value, pressed_threshold, released_threshold
leversize:[x,y,z], min_angle, max_angle, initial_angle
knobsize:{radius,depth}, min_angle, max_angle, initial_angle
slidersize:[x,y,z], travel, initial_value
wheelsize:{radius,depth}, periodic_detents?
joysticksize:{radius,length}, max_angle, target:{x,y}, detents with x/y
pedalsize:[x,y,z], travel_angle
crankarm_length, arm_size:{width,depth}, handle_radius, handle_length, periodic_detents?
pull_handlesize:[x,y,z], travel, initial_value; type:"pull_handle"

Common fields are id, key, optional name, type, position, rotation, mass and resistance. All types except wheel/crank also have auto_return, target, drive and detents. Dimensions and mass must be positive finite representable values; resistance is nonnegative. Drive uses max_force for button/slider/pull_handle, max_torque otherwise, plus frequency and damping.

Minimal control-only asset#

Syntax
{
  "format": "joltphysics-authoring",
  "version": 3,
  "configuration_id": "ad000000-0000-4000-8000-000000000001",
  "shapes": [],
  "controls": [{
    "id": "ad000000-0000-4000-8000-000000000002",
    "key": "start_button", "type": "button",
    "position": [0, 0, 0], "rotation": [0, 0, 0, 1],
    "size": [0.12, 0.12, 0.03], "mass": 0.15,
    "travel": 0.02, "initial_value": 0,
    "pressed_threshold": 0.8, "released_threshold": 0.6,
    "auto_return": true, "target": 0, "resistance": 0,
    "drive": {"max_force": 12, "frequency": 12, "damping": 1},
    "detents": []
  }]
}

Detents#

Scalar/joystick detents allow at most 256 unique positions. Serialized records require value (or x/y), capture_range, release_range, max_force/max_torque, frequency and damping. Require 0 < capture_range < release_range, positive effort/frequency and nonnegative damping. Auto Return takes priority; disable it when the mechanism should stay in detents.

Wheel/Crank periodic_detents requires count, capture_angle, release_angle, max_torque, frequency and damping. count is integer 1..3600; step=360/count, capture_angle ≤ step/2 and capture_angle < release_angle < min(step,45°). Omit the JSON field to disable. Runtime options accept false and shorthand {count:12}, with missing defaults supplied by the runtime validator.

Compatibility#

Field / operationMeaning and validation
0.17.0Button / Lever; JSON v3
0.18.0Knob / Slider
0.19.0Hand Wheel / Joystick
0.20.0Pedal / Crank
0.21.0Pull Handle

The current loader supports v1/v2/v3. Older loaders reject unsupported versions/types rather than silently dropping mechanisms. Update the addon and GML together. Existing categories keep their coordinate and lifetime contracts.

Simulation, rendering and lifetime#

Use the existing jolt_update() loop, then read the control's physical state. Drive your visual model with control.get_transform() or the existing control rendering API. The asset helper creates the same JoltControl bodies and constraints as the direct factory; it does not render your model or assign gameplay actions. Each creation is independent.

control.destroy() removes the mechanism and preserves its parent. Parent destruction and jolt_stop() clean up attached controls. Use managed lifecycle calls. No additional native bridge change is required by the Blender controls integration; use the matching current GML loader and jolt_asset_controls scripts.

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_asset_create_controljolt_asset_create_control(asset,control_ref,body,options=undefined)Asset, key/UUID, live host JoltBody + optional overrides/settings. Returns JoltControl or undefined. Allowed overrides depend on type; identity/type cannot change; unknown fields are errors. Partial drive/size merges are validated as a whole; source asset stays unchanged.
jolt_asset_get_controljolt_asset_get_control(asset,control_ref)Asset + exact key or UUID; returns an independent control record, undefined and error state on failure.