{"id":"reflectionnnn/spring","name":"spring","scope":"reflectionnnn","platform":"roblox","description":"Closure spring physics module.","version":"2.0.2","latest":"2.0.2","versions":["0.1.0","0.1.1","0.1.2","0.1.3","1.0.0","1.0.1","2.0.0","2.0.1","2.0.2"],"license":"MIT","licenseRating":"safe","licenseCaveats":[],"licenseVerified":true,"dependencies":{},"integrity":"6cad651cf812f49d3378e422f6af08fc16d444bc4d6cb1188cfda01b7d8cf2fe","likes":0,"downloads":0,"install":"forest install reflectionnnn/spring","url":"https://forest.dev/p/roblox/reflectionnnn/spring","files":"https://api.forest.dev/ai/package/roblox/reflectionnnn/spring/files","readme":"# Spring\r\n\r\nA high-performance, physics-based 3D spring simulation module for Luau. This module uses numerical integration with sub-stepping to provide stable and smooth motion, making it ideal for camera systems, procedural animations, and UI effects.\r\n\r\n[View Documentation](https://reflectionnnn.github.io/Spring/)\r\n\r\n\r\n## Features\r\n\r\n- **3D Vector Support**: Built natively for `Vector3` operations.\r\n- **Sub-stepping**: Maintain stability even at low or variable frame rates.\r\n- **Customizable Physics**: Fine-tune mass, force (stiffness), damping (friction), and speed.\r\n- **Type Safety**: Fully typed with Luau for excellent Luau LSP support.\r\n- **Lightweight**: Zero dependencies, simple closure-based API.\r\n\r\n## Installation\r\n\r\n### Manual\r\n- Go to Releases on github page.\r\n- Download .rbxm of latest release.\r\n\r\n### Wally\r\n- Visit https://wally.run/package/reflectionnnn/spring\r\n- Copy install command of latest version.\r\n- Add that to your `wally.toml`.\r\n```toml\r\nSpring = \"reflectionnnn/spring@VERSION\"\r\n```\r\n\r\n## Usage Example\r\n\r\n```lua\r\n-- Require spring\r\nlocal Spring = require(path.to.Spring)\r\n\r\n-- Create a new spring object (Mass, Force, Damping, Speed, Iterations)\r\n-- Or use default parameters \"local cameraSpring = Spring()\"\r\nlocal cameraSpring = Spring(4, 100, 4, 4, 16)\r\n\r\n-- Cache state to avoid unnecessary GC pressure\r\nlocal cachedState: Spring.PartialState = {\r\n  Target = Vector3.zero\r\n}\r\n\r\n-- Update loop (e.g., RunService.RenderStepped)\r\ngame:GetService(\"RunService\").PreSimulation:Connect(function(deltaTime: number)\r\n    -- Update cached state\r\n    cachedState.Target = workspace.CurrentCamera.CFrame.Position + Vector3.new(0, 10, 0)\r\n\r\n    -- Set the destination\r\n    cameraSpring.SetState(cachedState)\r\n\r\n    -- Advance the simulation and get the new Position\r\n    local newPosition = cameraSpring.Update(deltaTime)\r\n    \r\n    -- Apply to an object\r\n    somePart.Position = newPosition\r\nend)\r\n\r\n-- Apply an immediate kick (recoil/explosion)\r\ncameraSpring.ApplyImpulse(Vector3.new(0, 10, 0))\r\n\r\n-- Adjust stiffness or damping on the fly\r\ncameraSpring.SetState({\r\n    Force = 60,\r\n    Damping = 2\r\n})\r\n\r\n-- Get snapshot of current physical state\r\nlocal cameraState = cameraSpring.GetState()\r\nprint(cameraState.Velocity)\r\n```\r\n","readmeTruncated":false}