New: Sustain On Re-trigger (per reaction, off by default)
Built for ongoing contact rather than one-off hits. Turn it on when a reaction is driven by touch zones.
With it off (the old behaviour), every new touch restarts the movement from the beginning. If touches arrive faster than the Jerk Duration, the movement never gets far enough to settle — it just keeps re-starting, which looks like a fast stutter.
With it on, a touch during a movement no longer restarts it. The movement finishes, then the pose is held for as long as she’s being touched, and releases normally once you stop.
Each touch also nudges the force gently toward a new random value instead of snapping to it, so Motion Variability keeps the pose alive without the jitter.
Start and End Actions now fire once per movement instead of on every single touch event.
Especially useful when several touch zones are wired to the same reaction — each zone has its own cooldown, so together they can fire many times a second.
New: Min / Max Hold Duration
The single Hold Duration slider is now a pair, and the hold length is picked fresh at random in that range on every fire — so repeated reactions don’t all hold for exactly the same time.
Set both to the same number for a fixed hold. Both at 0 means no hold.
Your existing setting carries over automatically: an older scene or preset with one Hold value loads with both sliders set to that value, so nothing changes until you widen the range.
Improved: re-triggering blends instead of snapping
Previously, triggering a reaction while it was still moving dropped the force to zero and ramped up again, which gave a noticeable hitch.
It now continues upward from the force already applied, so repeated triggers build on each other smoothly.
Re-triggering during a hold simply extends the held pose.
Fixed: older presets with a single Intensity value
Very old presets saved before Min/Max Intensity existed were silently loading with the wrong intensity. They now convert correctly, setting both Min and Max to the saved value.
Compatibility
Nothing changes in existing scenes unless you switch Sustain On Re-trigger on yourself — it’s off by default on every reaction, new and old.
Scenes that pin an exact package version will keep using it. To pick up this build, reselect the plugin from version 6 in VaM’s plugin list and save the scene.
Fixed: renaming a reaction didn't update its trigger action. The trigger picker kept showing the old name until you reloaded the scene, and after a reload, any trigger wired to the old name broke.
Renamed reactions now show up in the trigger picker right away under the new name, and the old name is removed cleanly.
No more duplicate reaction names
Fixed: two reactions could end up with the same name (for example, adding a new one after deleting one from the middle of the list). When that happened, one of them silently disappeared from the trigger picker.
Every reaction name is now kept unique, whether it's added, pasted, renamed or loaded, and a number is added automatically if needed ("Reaction 3 2", "Hit Copy 2").
Switched from PC EA (early access ending Sep 16, 2026, with CC BY-ND as secondary) to plain CC BY-ND.
New features
Hold phase — new per-reaction Hold Duration (s) slider (0–5). The force now stays at peak for that time between jerk and return, so the body parks in a displaced pose instead of immediately recoiling. 0 (the default) skips the hold entirely, so old presets behave exactly as before.
Active toggle — master on/off bool on the left panel. When off, all incoming fire calls are ignored (reactions already in flight finish normally). It's a registered storable, so scene triggers can arm/disarm the whole plugin. Defaults ON for backward compatibility.
Global Cooldown (s) slider (0–30) — minimum time between any two fires across all reactions, separate from the per-reaction cooldown. Only a fire that actually starts stamps the timer; a call rejected for another reason (disabled reaction, per-reaction cooldown, no valid nodes) doesn't begin a cooldown.
Random groups (Timeline convention) — name reactions like flinch/left, flinch/right, flinch/duck and a single extra trigger action flinch/* appears that fires one of them at random. Only groups with 2+ members get the action; disabled members are skipped; it never repeats the last-fired reaction back-to-back. Group actions are rebuilt whenever reaction names change.
Transition Actions are now driven — the trigger's Transition tab (previously unused) receives the reaction's 0→1→0 envelope every physics tick: 0 at rest, 1 at peak jerk, pinned at 1 during hold, back to 0 on return. Any float target (gaze offsets, morphs, other plugins' params) rides the same easing curve as the body. This came out of the AutoThrusterPlus session where a gaze plugin owning the head was fighting SuddenMovements — now you drive the gaze plugin's own parameters instead of the controller.
Fixes / improvements
Test Trigger button now bypasses the Active gate and Global Cooldown, so you can preview while disarmed without consuming the scene's cooldown.
Reaction.Fire() returns a bool (whether it actually started) so the caller can distinguish a real fire from a rejected one.
Transition targets are settled to 0 before End Actions fire and on StopImmediate(), so driven values land back at their start.
Copy/Paste reaction now preserves the trigger (Start/End/Transition actions) instead of stripping it; restoration is deferred a frame via the same path scene loads use.
Copies are named "<name> Copy", "<name> Copy 2", … (appended) instead of "Copy of <name>" (prepended), so a copy of flinch/left stays in the flinch random group.
Save Preset now uses GetJSON(true, true, true) (forceStore) so storables sitting at their default value are still written — presets are self-contained rather than dependent on current defaults.
Null-atom path in Node.Resolve() now also clears ctrl, not just rb.
holdDuration is serialized to/from JSON and defaults to 0 when loading older reactions.
Help text expanded (height 1000 → 1400) with new sections: Master Controls, Random Groups, Triggers, and "Using Transitions With Other Plugins".
Switched from PC EA (early access ending Sep 16, 2026, with CC BY-ND as secondary) to plain CC BY-ND.
New features
Hold phase — new per-reaction Hold Duration (s) slider (0–5). The force now stays at peak for that time between jerk and return, so the body parks in a displaced pose instead of immediately recoiling. 0 (the default) skips the hold entirely, so old presets behave exactly as before.
Active toggle — master on/off bool on the left panel. When off, all incoming fire calls are ignored (reactions already in flight finish normally). It's a registered storable, so scene triggers can arm/disarm the whole plugin. Defaults ON for backward compatibility.
Global Cooldown (s) slider (0–30) — minimum time between any two fires across all reactions, separate from the per-reaction cooldown. Only a fire that actually starts stamps the timer; a call rejected for another reason (disabled reaction, per-reaction cooldown, no valid nodes) doesn't begin a cooldown.
Random groups (Timeline convention) — name reactions like flinch/left, flinch/right, flinch/duck and a single extra trigger action flinch/* appears that fires one of them at random. Only groups with 2+ members get the action; disabled members are skipped; it never repeats the last-fired reaction back-to-back. Group actions are rebuilt whenever reaction names change.
Transition Actions are now driven — the trigger's Transition tab (previously unused) receives the reaction's 0→1→0 envelope every physics tick: 0 at rest, 1 at peak jerk, pinned at 1 during hold, back to 0 on return. Any float target (gaze offsets, morphs, other plugins' params) rides the same easing curve as the body. This came out of the AutoThrusterPlus session where a gaze plugin owning the head was fighting SuddenMovements — now you drive the gaze plugin's own parameters instead of the controller.
Fixes / improvements
Test Trigger button now bypasses the Active gate and Global Cooldown, so you can preview while disarmed without consuming the scene's cooldown.
Reaction.Fire() returns a bool (whether it actually started) so the caller can distinguish a real fire from a rejected one.
Transition targets are settled to 0 before End Actions fire and on StopImmediate(), so driven values land back at their start.
Copy/Paste reaction now preserves the trigger (Start/End/Transition actions) instead of stripping it; restoration is deferred a frame via the same path scene loads use.
Copies are named "<name> Copy", "<name> Copy 2", … (appended) instead of "Copy of <name>" (prepended), so a copy of flinch/left stays in the flinch random group.
Save Preset now uses GetJSON(true, true, true) (forceStore) so storables sitting at their default value are still written — presets are self-contained rather than dependent on current defaults.
Null-atom path in Node.Resolve() now also clears ctrl, not just rb.
holdDuration is serialized to/from JSON and defaults to 0 when loading older reactions.
Help text expanded (height 1000 → 1400) with new sections: Master Controls, Random Groups, Triggers, and "Using Transitions With Other Plugins".