Skip to content

Player Ragdolls

Leo-T22 edited this page Jun 27, 2026 · 1 revision

Player Ragdolls

Player ragdolls are launched from a live ServerPlayer. The mod captures the player pose from the client, builds the ragdoll from Sable sublevels, and can seat the original player onto the simulated body so the camera follows the physics.

Launching

RagdollAPI.launch(player, velocity);
RagdollAPI.launch(player, velocity, despawnConditions);
RagdollAPI.launch(player, velocity, launchOptions);

launch() returns null in most cases because the pose is captured asynchronously from the client before the ragdoll is assembled. Use RagdollLaunchOptions to configure launch-time behavior up front, or call RagdollAPI.activeSession(player) once the ragdoll is already running.

Launch Options

RagdollLaunchOptions options = RagdollLaunchOptions.builder()
   .autoSeat(false)
   .despawnConditions(List.of(DespawnCondition.afterTicks(80)))
   .lockDismount(false)
   .build();

RagdollAPI.launch(player, velocityMetersPerSecond, options);

lockDismount(true) prevents the player from manually exiting the ragdoll via the keybind or interaction. The ragdoll will still end if the despawn conditions trigger or if session.release() is called.

To keep a player in ragdoll indefinitely until released by code:

RagdollAPI.launch(player, velocity, RagdollLaunchOptions.builder()
   .lockDismount(true)
   .despawnConditions(List.of(DespawnCondition.never()))
   .build());

// later, once the player is ragdolled:
RagdollSession session = RagdollAPI.activeSession(player);
if (session != null) session.release();

Despawn Conditions

DespawnCondition.afterTicks(ticks);
DespawnCondition.belowSpeed(metersPerSecond);
DespawnCondition.belowSpeedAfterTicks(metersPerSecond, minTicks);
DespawnCondition.never();
DespawnCondition.all(...);
DespawnCondition.any(...);

Per-Limb Pose And Joint Control

RagdollLimbOptions lets you set joint stiffness/damping for individual limbs. All fields are optional, unset limbs use the built-in defaults.

RagdollLimbOptions limbs = RagdollLimbOptions.builder()
   .limb(BodyPart.LEFT_ARM,  RagdollLimbConfig.builder().rotation(0, 0, 90))
   .limb(BodyPart.RIGHT_ARM, RagdollLimbConfig.builder().rotation(0, 0, -90))
   .limb(BodyPart.HEAD,      RagdollLimbConfig.builder().stiffness(120).damping(10))
   .build();

RagdollAPI.launch(player, velocity,
   RagdollLaunchOptions.builder().limbs(limbs).build());

rotation(pitchDegrees, yawDegrees, rollDegrees) sets the limb's rest angle. Individual axes can be set separately with .pitch(d), .yaw(d), and .roll(d).

Removing And Dismembering

Ragdolls can be removed later by UUID, even if you no longer hold the session object. Pass either the root sublevel UUID or any attached part UUID to remove the whole ragdoll. If the UUID belongs to a severed limb, only that loose limb is removed.

RagdollAPI.remove(level, rootOrPartSubLevelId);
RagdollAPI.remove(level, rootOrPartSubLevelId, true); // smoke puff + sound

Player ragdoll limbs can also be detached from the body. TORSO is the root and cannot be severed.

UUID limbId = RagdollAPI.dismember(level, rootSubLevelId, BodyPart.LEFT_ARM);

// Or resolve the ragdoll and limb from a clicked part:
UUID clickedLimbId = RagdollAPI.dismember(level, clickedPartSubLevelId);

Wailing Motor Effects

Wailing temporarily retargets joint motors for a twitching motion. Configure it as part of launch options so it applies automatically once the ragdoll assembles:

RagdollAPI.launch(player, velocity, RagdollLaunchOptions.builder()
   .wailing(RagdollWailingOptions.builder()
      .durationTicks(100)
      .stiffness(15.0)
      .intervalTicks(10)
      .startDelayTicks(2)
      .build())
   .build());

To apply or stop wailing on a ragdoll that is already active:

RagdollSession session = RagdollAPI.activeSession(player);
if (session != null) {
   session.applyWailing(RagdollWailingOptions.defaults());
   session.stopWailing();
}

By default, wailing waits 2 ticks before the first retarget so the ragdoll can finish spawning cleanly.

Clone this wiki locally