From 5bd0dadfdf9d6d81d7db4374983e40de00effecb Mon Sep 17 00:00:00 2001 From: Thomas Hallock Date: Wed, 22 Oct 2025 19:50:00 -0500 Subject: [PATCH] perf(complement-race): increase spring animation responsiveness to reduce lag MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Increased spring animation config from tension:280/friction:60 to tension:600/friction:35 for both local and ghost trains. This makes the animations much more responsive and reduces visual lag behind the actual game state position. The previous slow springs caused the visual train to lag noticeably behind the actual position, especially when answering questions (which adds momentum and increases speed). The train would appear "stuck" even though position was updating correctly in the game loop. The new faster config still provides smooth interpolation to hide 100ms update jitter, but responds quickly enough to avoid noticeable lag. Changes: - useTrainTransforms: Update locomotive and car spring configs to tension:600, friction:35 - GhostTrain: Update locomotive and car spring configs to match local train Fixes: - Train now moves immediately when answering questions - No more "needing multiple answers" to see train movement - Reduces perceived flashing/stuttering from render lag 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .../complement-race/components/RaceTrack/GhostTrain.tsx | 4 ++-- .../app/arcade/complement-race/hooks/useTrainTransforms.ts | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/web/src/app/arcade/complement-race/components/RaceTrack/GhostTrain.tsx b/apps/web/src/app/arcade/complement-race/components/RaceTrack/GhostTrain.tsx index 6633b8b7..ce7db64d 100644 --- a/apps/web/src/app/arcade/complement-race/components/RaceTrack/GhostTrain.tsx +++ b/apps/web/src/app/arcade/complement-race/components/RaceTrack/GhostTrain.tsx @@ -89,7 +89,7 @@ export function GhostTrain({ y: locomotiveTarget?.y ?? 0, rotation: locomotiveTarget?.rotation ?? 0, opacity: locomotiveTarget?.opacity ?? 1, - config: { tension: 280, friction: 60 }, // Smooth but responsive + config: { tension: 600, friction: 35 }, // Fast/responsive to match local train }) // Calculate target transforms for cars (used by spring animations) @@ -133,7 +133,7 @@ export function GhostTrain({ y: target.y, rotation: target.rotation, opacity: target.opacity, - config: { tension: 280, friction: 60 }, + config: { tension: 600, friction: 35 }, // Fast/responsive to match local train })) ) diff --git a/apps/web/src/app/arcade/complement-race/hooks/useTrainTransforms.ts b/apps/web/src/app/arcade/complement-race/hooks/useTrainTransforms.ts index 96083a8e..f1cac82f 100644 --- a/apps/web/src/app/arcade/complement-race/hooks/useTrainTransforms.ts +++ b/apps/web/src/app/arcade/complement-race/hooks/useTrainTransforms.ts @@ -41,7 +41,7 @@ export function useTrainTransforms({ x: locomotiveTarget.x, y: locomotiveTarget.y, rotation: locomotiveTarget.rotation, - config: { tension: 280, friction: 60 }, + config: { tension: 600, friction: 35 }, // Fast/responsive to avoid lag }) // Calculate target transforms for train cars (each car follows behind the locomotive) @@ -98,7 +98,7 @@ export function useTrainTransforms({ rotation: target.rotation, opacity: target.opacity, position: target.position, - config: { tension: 280, friction: 60 }, + config: { tension: 600, friction: 35 }, // Fast/responsive to avoid lag })) ) @@ -128,7 +128,7 @@ export function useTrainTransforms({ // Animated spring for smooth locomotive opacity const locomotiveOpacity = useSpring({ opacity: locomotiveOpacityTarget, - config: { tension: 280, friction: 60 }, + config: { tension: 600, friction: 35 }, // Fast/responsive to avoid lag }) return {