From 86dee3c87c7d23938fe34baaf794d6b74549f80d Mon Sep 17 00:00:00 2001 From: Kaan <81116098+kaan650@users.noreply.github.com> Date: Mon, 19 Oct 2026 14:05:23 +0300 Subject: [PATCH 1/2] Fix springs not finishing when moving to zero (#98) --- src/spring.luau | 13 +++++++++++-- test/tests.luau | 26 ++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/src/spring.luau b/src/spring.luau index ef7decf..63a308f 100644 --- a/src/spring.luau +++ b/src/spring.luau @@ -10,6 +10,7 @@ local push_scope_as_child_of = graph.push_scope_as_child_of local UPDATE_RATE = 120 local TOLERANCE_FACTOR = 10_000 +local MIN_TOLERANCE = vector.create(1e-6, 1e-6, 1e-6) type Animatable = number | CFrame | Color3 | UDim | UDim2 | Vector2 | Vector3 @@ -170,6 +171,7 @@ local function spring(source: () -> T, period: number?, damping_ratio: number local function updater_effect() local value = source() + data.x0_123, data.x0_456 = data.x_123, data.x_456 data.x1_123, data.x1_456 = type_to_vec6[typeof(value)](value) data.source_value = value springs[data] = output @@ -219,6 +221,7 @@ local function spring(source: () -> T, period: number?, damping_ratio: number -- set current position to value local v = ... :: T data.x_123, data.x_456 = type_to_vec6[typeof(v)](v) + data.x0_123, data.x0_456 = data.x_123, data.x_456 -- reset velocity data.v_123 = vector.zero @@ -246,6 +249,12 @@ local function get_min_vector_step(direction: vector): vector ) end +-- relative to the distance travelled, with a floor so springs can still settle at zero and large goals +local function get_tolerance(x0: vector, x1: vector): vector + local distance = vector.max(vector.abs(x0 - x1), vector.abs(x1)) + return vector.max(get_min_vector_step(distance), MIN_TOLERANCE) +end + local function step_springs(dt: number) for s in springs do local k = s.k @@ -290,8 +299,8 @@ local function update_spring_sources() local x1_123, x1_456 = data.x1_123, data.x1_456 local v_123, v_456 = data.v_123, data.v_456 - local tol_123 = vector.abs(get_min_vector_step(x0_123 - x1_123)) - local tol_456 = vector.abs(get_min_vector_step(x0_456 - x1_456)) + local tol_123 = get_tolerance(x0_123, x1_123) + local tol_456 = get_tolerance(x0_456, x1_456) if -- position is at goal (within tolerance) diff --git a/test/tests.luau b/test/tests.luau index af6a7f4..cd9cd1d 100644 --- a/test/tests.luau +++ b/test/tests.luau @@ -2121,6 +2121,32 @@ TEST("spring()", wrap_root(function() CHECK(count == 1) -- check spring was rescheduled correctly end + do CASE "spring finished at zero" + local input = source(1) + local output, control = spring(input) + + local count = 0 + effect(function() + output() + count += 1 + end) + + input(0) + step(10) + CHECK(output() == 0) + + count = 0 + step(1) + CHECK(count == 0) -- check spring is finished + + control { impulse = 1 } + step(10) + + count = 0 + step(1) + CHECK(count == 0) -- check spring is finished after impulse at rest + end + do CASE "spring control" local input = source(1) local output, control = spring(input) From a4151bd41ed06592d81a622c7185c6ef123c80b9 Mon Sep 17 00:00:00 2001 From: Kaan <81116098+kaan650@users.noreply.github.com> Date: Mon, 19 Oct 2026 14:06:53 +0300 Subject: [PATCH 2/2] Fix error message when setting an invalid member (#99) --- src/lib.luau | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.luau b/src/lib.luau index 99fbd7a..beae180 100644 --- a/src/lib.luau +++ b/src/lib.luau @@ -112,7 +112,7 @@ setmetatable(vide :: any, { __newindex = function(_, index: unknown, value: unknown) if flags[index] == nil then - error(`{tostring(index)} is not a valid member of vide, 0`) + error(`{tostring(index)} is not a valid member of vide`, 0) else flags[index] = value end