Sable organizes forces applied to sub-levels into namedDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/ryanhcode/sable/llms.txt
Use this file to discover all available pages before exploring further.
ForceGroup buckets. Each tick, block entities and system-level providers (gravity, drag, lift, propulsion) accumulate linear and angular impulses into their respective group’s ForceTotal. At the end of the physics substep, all totals are flushed to the rigid body via RigidBodyHandle.applyForcesAndReset(). This design makes force contributions inspectable and separable in the GUI.
ForceGroup
ForceGroup is a named, colored category for grouping force contributions. It is a registry object stored in the sable:force_groups registry.
A translatable display name for this group (e.g. shown in the contraption GUI).
An optional longer description. May be
null.An RGB integer color used when rendering force vectors in the debug overlay.
Whether this group’s force vectors are shown by default in the GUI without the user enabling them.
ForceGroups
ForceGroups is the registry for all built-in force groups and exposes the registry itself for iteration.
Built-in groups
| Field | Registry path | Default displayed |
|---|---|---|
GRAVITY | sable:gravity | No |
DRAG | sable:drag | No |
LEVITATION | sable:levitation | Yes |
BALLOON_LIFT | sable:balloon_lift | Yes |
PROPULSION | sable:propulsion | Yes |
LIFT | sable:lift | Yes |
MAGNETIC_FORCE | sable:magnetic_force | No |
count
ForceTotal
ForceTotal accumulates local linear and angular impulses within a single physics substep and then flushes them to a RigidBodyHandle. It is the primary accumulator used by QueuedForceGroup and RigidBodyHandle.applyForcesAndReset().
Forces are expressed in the local frame of the sub-level unless otherwise noted.
applyLinearAndAngularImpulse
applyLinearImpulse
applyAngularImpulse
applyTorqueImpulse
applyAngularImpulse — adds a local torque [Nm].
applyImpulseAtPoint(MassData, Vector3dc, Vector3dc)
Provides the center-of-mass used for torque calculation.
Application point inside the plot [m].
Force to apply [N].
applyImpulseAtPoint(ServerSubLevel, Vector3dc, Vector3dc)
ServerSubLevel.getMassTracker().
applyImpulseAtPoint(MassTracker, Vec3, Vec3)
Vec3 arguments for interoperability with Minecraft code.
applyForceTotal
other into this total.
reset
applyForces flushes to the engine.
getLocalForce
getLocalTorque
QueuedForceGroup
QueuedForceGroup is a per-sub-level, per-ForceGroup accumulator that additionally records individual point forces for debug visualization when the sub-level’s tracking is enabled.
Obtain an instance via ServerSubLevel.getOrCreateQueuedForceGroup(ForceGroup).
Constructor
getForceTotal
ForceTotal accumulator for this group. Add forces here.
applyAndRecordPointForce
World position of the force application point inside the plot [m].
Force vector [N].
recordPointForce
ServerSubLevel.isTrackingIndividualQueuedForces() returns true and the force magnitude exceeds 0.001 N.
getRecordedPointForces
reset(). Each entry is a PointForce(Vector3dc point, Vector3dc force) record.
reset
MassData
Methods
Total mass in kilo-Minecraft-physics-grams (kpg).
1 / mass [1/kpg]. Returns 0 if mass is 0 (invalid).Inertia tensor in local space [kpg·m²].
Inverse inertia tensor in local space [1/(kpg·m²)].
Center-of-mass position in local (plot-relative) space [m]. May be
null if the body has no solid blocks.Returns
true when getMass() <= 0. Indicates no solid blocks or uninitialized state.getInverseNormalMass
position along direction. Used for impulse-based collision resolution.
MassTracker
MassTracker is the concrete, mutable implementation of MassData for sub-levels. It is built once during assembly via MassTracker.build() and updated incrementally as blocks are added or removed.
build
MassTracker from all solid blocks within bounds, computing the aggregate mass, center-of-mass, and inertia tensor using the parallel-axis theorem.
addBlockMass
blockMass is negative) a block’s contribution to the tracker using the parallel-axis theorem.
moveCenterOfMass
newCenterOfMass and adjusts the inertia tensor accordingly.
BLOCK_CENTER_OF_MASS
BlockState. Respects BlockSubLevelCustomCenterOfMass overrides. Results are cached by block-state hash code.
BoxPhysicsObject and BoxHandle
BoxPhysicsObject is a standalone cuboid rigid body not tied to any sub-level. It is useful for projectiles, debris, or other physics objects that have no associated block data.
BoxPhysicsObject
Initial world-space pose. Rotation and scale components of the pose are ignored; only position is used.
Half-sizes of the box along each axis [m].
Mass of the box [kpg].
| Method | Description |
|---|---|
getPose() | Returns the last pose read back from the engine. Call updatePose() first. |
getHalfExtents() | Returns the box’s half-extents. |
getMass() | Returns the box mass [kpg]. |
isActive() | Returns true while the box is registered in the physics world. |
updatePose() | Queries the physics engine and updates the stored pose. |
wakeUp() | Wakes the box. |
BoxHandle
PhysicsPipeline.addBox().
| Method | Description |
|---|---|
readPose(Pose3d dest) | Queries the current pose from the engine into dest. |
remove() | Removes the box from the pipeline. |
wakeUp() | Wakes the box. |
getRuntimeId() | Returns the runtime ID assigned by the pipeline. |
RopePhysicsObject and RopeHandle
RopePhysicsObject simulates a chain of point masses with distance constraints, suitable for hanging ropes, cables, and chains.
RopePhysicsObject
The initial world-space positions of the rope’s nodes, ordered from start to end.
The radius of each rope segment’s capsule collider [m].
| Method | Description |
|---|---|
getPoints() | Returns an unmodifiable view of the current node positions. |
getCollisionRadius() | Returns the collision radius [m]. |
updatePose() | Reads updated node positions from the physics engine. |
addPoint(Vector3dc) | Prepends a node to the start of the rope. |
removeFirstPoint() | Removes the first (start) node. |
setFirstSegmentLength(double) | Sets the extension constraint length of the first segment [m]. |
setAttachment(AttachmentPoint, Vector3dc, ServerSubLevel) | Attaches an endpoint to a position on a sub-level. |
isActive() | Returns true while the rope is registered in the physics world. |
RopeHandle
PhysicsPipeline.addRope().
| Method | Description |
|---|---|
readPose(List<Vector3d> dest) | Reads current node positions into dest. |
remove() | Removes the rope from the pipeline. |
addPoint(Vector3dc) | Prepends a node. |
removeFirstPoint() | Removes the first node. |
setFirstSegmentLength(double) | Sets the extension constraint length of the first segment. |
setAttachment(AttachmentPoint, Vector3dc, ServerSubLevel) | Attaches an endpoint. |
wakeUp() | Wakes all rope segments. |
