Thrust Spring (Stop-Spring)
A subtle “suspension” effect that lets the ship coast a little further than its
drag curve would otherwise allow once it gets near a full stop. Named in code
as stopSpringAmt — the per-ship stat that controls how much the spring
reduces drag in the final approach to zero velocity.
Feel
When you release thrust at any meaningful speed, the configured dragCurve
(exponential, linear, front_loaded, back_loaded, or overshoot) bleeds
velocity off in the normal way. As the ship drops below a threshold of 15 u/s
and is no longer thrusting, the spring kicks in: drag is softened so the ship
drifts a bit past where it would have stopped and then settles. The intended
sensation is a car’s suspension absorbing the last of the momentum, or a
hovercraft easing onto its pad.
This is a physics effect, not a sprite-only tween. The body’s vx/vy
themselves decay more slowly during the final glide.
How it works (engine/physics/movement.ts)
The relevant code lives at the end of the per-frame drag block in
Physics.update:
// stopSpringAmt: below STOP_SPEED_THRESHOLD, weaken drag so the ship
// coasts a little further before fully stopping.
if ((ship.stopSpringAmt ?? 0) > 0 && !playerInput.isThrusting && currentSpeedForDrag < STOP_SPEED_THRESHOLD) {
const t = currentSpeedForDrag / STOP_SPEED_THRESHOLD;
const springMul = 1 - ship.stopSpringAmt * (1 - t);
dragArg = 1 - (1 - dragArg) * Math.max(0.05, springMul);
}
ship.vx *= dragArg;
ship.vy *= dragArg;Three gating conditions, all required:
stopSpringAmt > 0— the ship’s per-hull stat is non-zero.!playerInput.isThrusting— the player has let go of thrust.currentSpeedForDrag < STOP_SPEED_THRESHOLD— current speed is underSTOP_SPEED_THRESHOLD = 15u/s (the same threshold that triggers the one-shot stop-shake camera signal on a hard stop).
When gated in, t is a 0→1 progress through the threshold band. springMul
starts at 1 - stopSpringAmt at zero speed and rises back to 1 at the
threshold. That value multiplies into (1 - dragArg) — the bit of drag the
exponential decay was about to apply — and shrinks it, but never below 5% of
the original drag (Math.max(0.05, ...)). So the ship still slows; it just
slows less in the last fifteen units of speed.
Tuning surface
Defined on the ship def in data/ships.ts:
/** Spring-back amount when stopping. 0 = no overshoot. Small positive values cause
* the ship to drift a tiny bit past zero velocity and then settle (like a car's
* suspension absorbing momentum). Typical: 0.05-0.15. */
stopSpringAmt: number;0— no spring. Drag curve runs cleanly to zero. Current default for every ★1 hull inSHIP_STATS_S1and every fully-defined ship def in the file.0.05–0.15— typical authored range when a designer wants the feel.- Higher values bias the late-stop band toward longer coast; the floor of
0.05onspringMulprevents the ship from becoming undamped (it can never fully stop coasting once gated in).
The field lives on BASELINE_STATS (default 0), is listed in the canonical
SHIP_STAT_FIELDS array, and is upgradeable through the standard ★1→★5 stat
lerp pipeline.
Related
- Drag curves — the broader system of how thrust-off deceleration shapes.
stopSpringAmtis a final-approach modifier that runs after whichever curve is active. - Stop-shake — uses the same
STOP_SPEED_THRESHOLD = 15 u/sboundary. Crossing down through it while not thrusting fires the one-shot camera shake; the spring acts on the other side of that crossing to delay the exact moment of full stop. engine/core/types.tsanddata/run-config.tsmirror the field on the live ship state and run-config respectively.
Source map
src/starship-survivors/engine/physics/movement.ts—STOP_SPEED_THRESHOLDconstant (line ~33) + spring branch insidePhysics.update(lines ~326–332).src/starship-survivors/data/ships.ts—stopSpringAmtfield onShipDef(line ~99),BASELINE_STATSdefault (line ~198),SHIP_STAT_FIELDSentry (line ~341), and per-hull ★1 entries inSHIP_STATS_S1.src/starship-survivors/engine/core/types.ts—stopSpringAmton the live ship state shape (line ~639).src/starship-survivors/data/run-config.ts— run-config mirror (line ~165).src/starship-survivors/screens/playground/ShipsTab.tsx— designer-facing tuning surface in the dev playground.