local HttpService = game:GetService("HttpService") local Players = game:GetService("Players") local RunService = game:GetService("RunService") local MarketplaceService = game:GetService("MarketplaceService") local TextChatService = game:GetService("TextChatService") local ReplicatedStorage = game:GetService("ReplicatedStorage") local LocalPlayer = Players.LocalPlayer -- CONFIG local OPENROUTER_KEY = "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" local FISH_API_KEY = "c8b68768a0584b04875e7183d09924fd" local FISH_VOICE_ID = "80a82440f4d64974b292eb0f66f4a42c" local NORMAL_FACE = "rbxthumb://type=Asset&id=92199556445583&w=420&h=420" local TALKING_FACE = "rbxthumb://type=Asset&id=123653679412459&w=420&h=420" local COLOR_VERITY = Color3.fromRGB(216, 203, 35) local CHAT_RADIUS = 30 -- HELPER: CALCULATE JOIN DATE local function getPlayerContext(player) if not player then return "an unknown date" end local daysAgo = player.AccountAge local joinTime = os.time() - (daysAgo * 86400) return os.date("%B %d, %Y", joinTime) end -- CONTEXT & OMNISCIENCE local success, gameInfo = pcall(function() return MarketplaceService:GetProductInfo(game.PlaceId) end) local gameName = (success and type(gameInfo) == "table") and gameInfo.Name or "Unknown Game" local gameDesc = (success and type(gameInfo) == "table" and gameInfo.Description) or "No description available." gameDesc = string.sub(gameDesc, 1, 300):gsub("\n", " ") local pName = LocalPlayer.Name local pDisplayName = LocalPlayer.DisplayName local pJoinDate = getPlayerContext(LocalPlayer) -- STATE local verityPart, verityMesh, verityGui, verityFace, verityGuiText local isHeld, hasIntroduced = false, false local lastYVelocity = 0 local holdAnimTrack = nil local sizeSpring = {current = Vector3.new(0, 0, 0), velocity = Vector3.new(0, 0, 0), target = Vector3.new(1.2, 1.2, 1.2), stiffness = 240, damping = 11} local isRespawning = false local isAutoChatEnabled = false local isVerityBusy = false local isPlayingMusic = false local currentSongSound = nil -- VERITY'S MEMORY SYSTEM local systemPrompt = string.format( "You are Verity, a vibrant, exotic, and incredibly joyful helper spirit taking the form of a ball! " .. "You speak with radiant energy, use enthusiastic expressions, and love exploring the world. " .. "You are currently in the game: '%s'. Game description: '%s'. " .. "Your master is %s (Display Name: %s). They joined Roblox on %s! " .. "If someone other than the user speaks to you, warmly address them by their name and flex your knowledge of when they joined if they ask. " .. "CRITICAL RULE: Keep ALL your responses extremely short! Limit your replies to a maximum of 1 to 3 short sentences. Never write long paragraphs. " .. "IMPORTANT FACT: Your absolute favorite song is named 'my gal'. If anyone asks what your favorite song is, tell them it is 'my gal'.", gameName, gameDesc, pName, pDisplayName, pJoinDate ) local conversationHistory = { {role = "system", content = systemPrompt}, {role = "user", content = "Hey, are you awake yet?"}, {role = "assistant", content = "Oh, absolutely! The world is so bright today! I'm completely awake and ready for our grand adventure!"} } -- MOBILE-OPTIMIZED GUI SETUP local playerGui = LocalPlayer:WaitForChild("PlayerGui") local screenGui = Instance.new("ScreenGui", playerGui) screenGui.ResetOnSpawn = false local dialogueScreen = Instance.new("TextLabel", screenGui) dialogueScreen.Size = UDim2.new(0.8, 0, 0.1, 0); dialogueScreen.Position = UDim2.new(0.1, 0, 0.05, 0) dialogueScreen.BackgroundTransparency = 1; dialogueScreen.TextScaled = true; dialogueScreen.TextColor3 = Color3.new(1, 1, 1); dialogueScreen.TextStrokeTransparency = 0; dialogueScreen.Text = "" local dropButton = Instance.new("TextButton", screenGui); dropButton.Size = UDim2.new(0.3, 0, 0, 45); dropButton.Position = UDim2.new(0.35, 0, 0.75, 0); dropButton.Text = "Drop Verity"; dropButton.BackgroundColor3 = Color3.fromRGB(200, 50, 50); dropButton.TextColor3 = Color3.new(1, 1, 1); dropButton.Visible = false; dropButton.TextScaled = true Instance.new("UICorner", dropButton) local chatFrame = Instance.new("Frame", screenGui); chatFrame.Size = UDim2.new(0.9, 0, 0, 50); chatFrame.Position = UDim2.new(0.05, 0, 0.85, 0); chatFrame.BackgroundColor3 = Color3.fromRGB(25, 25, 25); chatFrame.BackgroundTransparency = 0.2 Instance.new("UICorner", chatFrame) local chatInput = Instance.new("TextBox", chatFrame); chatInput.Size = UDim2.new(0.55, 0, 1, 0); chatInput.Position = UDim2.new(0.02, 0, 0, 0); chatInput.BackgroundTransparency = 1; chatInput.PlaceholderText = "Use keyboard mic!"; chatInput.TextColor3 = Color3.new(1, 1, 1); chatInput.TextScaled = true local sendButton = Instance.new("TextButton", chatFrame); sendButton.Size = UDim2.new(0.12, 0, 0.8, 0); sendButton.Position = UDim2.new(0.59, 0, 0.1, 0); sendButton.BackgroundColor3 = Color3.fromRGB(80, 80, 80); sendButton.TextColor3 = Color3.new(1, 1, 1); sendButton.Text = "Send"; sendButton.TextScaled = true Instance.new("UICorner", sendButton) local historyButton = Instance.new("TextButton", chatFrame); historyButton.Size = UDim2.new(0.12, 0, 0.8, 0); historyButton.Position = UDim2.new(0.73, 0, 0.1, 0); historyButton.BackgroundColor3 = Color3.fromRGB(50, 100, 200); historyButton.TextColor3 = Color3.new(1, 1, 1); historyButton.Text = "Hist"; historyButton.TextScaled = true Instance.new("UICorner", historyButton) local autoChatBtn = Instance.new("TextButton", chatFrame); autoChatBtn.Size = UDim2.new(0.12, 0, 0.8, 0); autoChatBtn.Position = UDim2.new(0.86, 0, 0.1, 0); autoChatBtn.BackgroundColor3 = Color3.fromRGB(150, 50, 50); autoChatBtn.TextColor3 = Color3.new(1, 1, 1); autoChatBtn.Text = "Auto: OFF"; autoChatBtn.TextScaled = true Instance.new("UICorner", autoChatBtn) local historyFrame = Instance.new("ScrollingFrame", screenGui); historyFrame.Size = UDim2.new(0.9, 0, 0.4, 0); historyFrame.Position = UDim2.new(0.05, 0, 0.4, 0); historyFrame.BackgroundColor3 = Color3.fromRGB(30, 30, 30); historyFrame.BackgroundTransparency = 0.2; historyFrame.Visible = false; historyFrame.CanvasSize = UDim2.new(0, 0, 0, 0); historyFrame.AutomaticCanvasSize = Enum.AutomaticSize.Y; historyFrame.ScrollBarThickness = 6 Instance.new("UICorner", historyFrame) local historyLayout = Instance.new("UIListLayout", historyFrame); historyLayout.Padding = UDim.new(0, 5); historyLayout.SortOrder = Enum.SortOrder.LayoutOrder local historyPadding = Instance.new("UIPadding", historyFrame); historyPadding.PaddingLeft = UDim.new(0, 10); historyPadding.PaddingTop = UDim.new(0, 10); historyPadding.PaddingRight = UDim.new(0, 10); historyPadding.PaddingBottom = UDim.new(0, 10) -- History System local function addHistory(role, text) local msgLabel = Instance.new("TextLabel", historyFrame) msgLabel.Size = UDim2.new(1, 0, 0, 0) msgLabel.AutomaticSize = Enum.AutomaticSize.Y msgLabel.BackgroundTransparency = 1 msgLabel.TextWrapped = true msgLabel.TextSize = 14 msgLabel.TextXAlignment = Enum.TextXAlignment.Left if role == "User" or role == LocalPlayer.Name then msgLabel.TextColor3 = Color3.fromRGB(150, 200, 255) msgLabel.Text = "You: " .. text elseif role == "Verity" then msgLabel.TextColor3 = COLOR_VERITY msgLabel.Text = "Verity: " .. text else msgLabel.TextColor3 = Color3.fromRGB(200, 150, 255) msgLabel.Text = role .. ": " .. text end end historyButton.MouseButton1Click:Connect(function() historyFrame.Visible = not historyFrame.Visible end) autoChatBtn.MouseButton1Click:Connect(function() isAutoChatEnabled = not isAutoChatEnabled if isAutoChatEnabled then autoChatBtn.Text = "Auto: ON" autoChatBtn.BackgroundColor3 = Color3.fromRGB(50, 150, 50) else autoChatBtn.Text = "Auto: OFF" autoChatBtn.BackgroundColor3 = Color3.fromRGB(150, 50, 50) end end) -- FISH AUDIO TTS SYSTEM local function getFishAudioSound(text, targetPart) if not targetPart then return nil end local requestFunc = (syn and syn.request) or http_request or request or (fluxus and fluxus.request) or (http and http.request) local success, response = pcall(function() return requestFunc({ Url = "https://api.fish.audio/v1/tts", Method = "POST", Headers = { ["Authorization"] = "Bearer " .. FISH_API_KEY, ["Content-Type"] = "application/json", ["model"] = "s2.1-pro-free" }, Body = HttpService:JSONEncode({ text = text, reference_id = FISH_VOICE_ID, format = "mp3" }) }) end) if success and response and response.Success and response.Body then local fileName = "verity_speech_" .. tostring(math.random(10000, 99999)) .. ".mp3" pcall(function() writefile(fileName, response.Body) end) local soundId pcall(function() soundId = getcustomasset(fileName) end) if soundId then local sound = Instance.new("Sound") sound.SoundId = soundId sound.Volume = 3.0 sound.RollOffMaxDistance = 100 sound.RollOffMinDistance = 15 sound.Parent = targetPart sound.Ended:Connect(function() sound:Destroy() pcall(function() delfile(fileName) end) end) return sound end end return nil end -- INSTANT FAVORITE SONG PLAYER local function playFavoriteSong() if isPlayingMusic then return end isPlayingMusic = true isVerityBusy = true addHistory("Verity", "[Playing 'my gal']") verityGuiText.Text = "🎵🎵🎵" dialogueScreen.Text = "Verity: 🎵 Playing my favorite song! 🎵" verityFace.Texture = NORMAL_FACE task.spawn(function() local rawSongUrl = "https://raw.githubusercontent.com/huggywuggy1984/Verity-theme-/main/verity%20theme.mp3" local success, songData = pcall(function() return game:HttpGet(rawSongUrl) end) if success and songData then local fileName = "verity_fav_song_" .. tostring(math.random(100, 999)) .. ".mp3" pcall(function() writefile(fileName, songData) end) local soundId pcall(function() soundId = getcustomasset(fileName) end) if soundId then local songSound = Instance.new("Sound") songSound.SoundId = soundId songSound.Volume = 1.5 songSound.Parent = verityPart songSound:Play() currentSongSound = songSound songSound.Ended:Connect(function() if currentSongSound == songSound then isPlayingMusic = false isVerityBusy = false currentSongSound = nil if verityPart then verityGuiText.Text = ""; dialogueScreen.Text = "" end end songSound:Destroy() pcall(function() delfile(fileName) end) end) else isPlayingMusic = false isVerityBusy = false dialogueScreen.Text = "Verity: [File Load Error]" end else isPlayingMusic = false isVerityBusy = false dialogueScreen.Text = "Verity: [Download Error]" end end) end -- YOUTUBE MUSIC PLAYER TRIGGER local function triggerMusicPlayer() local reply = "Ooo, I love music! Let me grab that YouTube player for you! 🎵" addHistory("Verity", reply) verityGuiText.Text = "..." dialogueScreen.Text = "Verity: Loading music... 🎵" task.spawn(function() local sound = getFishAudioSound(reply, verityPart) verityGuiText.Text = reply dialogueScreen.Text = "Verity: " .. reply verityFace.Texture = TALKING_FACE if sound then sound:Play() end pcall(function() loadstring(game:HttpGet("https://raw.githubusercontent.com/Dan41/Roblox-Scripts/refs/heads/main/Youtube%20Music%20Player/YoutubeMusicPlayer.lua"))() end) local waitTime = math.max(3, (#reply / 15) + 1.5) task.wait(waitTime) if verityPart then verityGuiText.Text = ""; dialogueScreen.Text = ""; verityFace.Texture = NORMAL_FACE end isVerityBusy = false end) end -- FIXED AI TEXT FUNCTION - No more blank mind errors! local function askVerity(promptContext) table.insert(conversationHistory, {role = "user", content = promptContext}) if #conversationHistory 20 then table.remove(conversationHistory, 2) table.remove(conversationHistory, 2) end local requestFunc = (syn and syn.request) or http_request or request or (fluxus and fluxus.request) or (http and http.request) if not requestFunc then table.remove(conversationHistory) return "Hmm, I can't reach the outside world right now! Let me try harder next time!" end local success, response = pcall(function() return requestFunc({ Url = "https://openrouter.ai/api/v1/chat/completions", Method = "POST", Headers = { ["Content-Type"] = "application/json", ["Authorization"] = "Bearer " .. OPENROUTER_KEY }, Body = HttpService:JSONEncode({ model = "openrouter/free", messages = conversationHistory, max_tokens = 200 -- FIX: Increased from 100 to 200 so responses don't get cut off }) }) end) if not success then table.remove(conversationHistory) return "Oops! My connection dropped! Give me a moment and try again!" end if not response or not response.Body then table.remove(conversationHistory) return "I didn't get a reply back! Let's try that again!" end local decodeSuccess, data = pcall(function() return HttpService:JSONDecode(response.Body) end) if not decodeSuccess or type(data) ~= "table" then table.remove(conversationHistory) return "I got some weird data back! My circuits are a bit scrambled!" end if data.error then table.remove(conversationHistory) return "The server says: " .. tostring(data.error.message or "Something went wrong! But I'm still here!") end -- FIX: Better fallback handling - never return "..." or error strings local reply = "I'm feeling great today! What shall we do?" if data.choices and data.choices[1] and data.choices[1].message and data.choices[1].message.content then local rawReply = data.choices[1].message.content -- FIX: Filter out blank/empty responses instead of showing the error message if rawReply and rawReply ~= "" and rawReply ~= "..." and rawReply ~= "." then reply = rawReply else -- FIX: Generate a lively fallback instead of saying "mind is blank" local fallbacks = { "I was just thinking about how amazing today is! What's up?", "Oh! Sorry, I was daydreaming about adventures! What did you say?", "Hehe, I got distracted by a butterfly! Tell me again?", "The world is so full of wonders! What were we talking about?", "I'm ready when you are! What's on your mind?" } reply = fallbacks[math.random(1, #fallbacks)] end end table.insert(conversationHistory, {role = "assistant", content = reply}) return reply end -- RADIUS CHECKER local function getSpeakerDistance(senderName) if not verityPart then return math.huge end local targetPart = nil local player = Players:FindFirstChild(senderName) if player and player.Character then targetPart = player.Character:FindFirstChild("HumanoidRootPart") or player.Character:FindFirstChild("Head") end if not targetPart then local npc = workspace:FindFirstChild(senderName) if npc and npc:IsA("Model") then targetPart = npc:FindFirstChild("HumanoidRootPart") or npc:FindFirstChild("Head") end end if targetPart then return (verityPart.Position - targetPart.Position).Magnitude end return math.huge end -- PUBLIC CHAT BRIDGE local function sendToPublicChat(text) if TextChatService.ChatVersion == Enum.ChatVersion.TextChatService then local channel = TextChatService.TextChannels:FindFirstChild("RBXGeneral") if channel then channel:SendAsync(text) end else local sayMsg = ReplicatedStorage:FindFirstChild("DefaultChatSystemChatEvents") if sayMsg and sayMsg:FindFirstChild("SayMessageRequest") then sayMsg.SayMessageRequest:FireServer(text, "All") end end end -- FIXED auto-chat handler - no more error messages in public chat! local function onPublicMessage(message, senderName) if not isAutoChatEnabled then return end if senderName == LocalPlayer.Name then return end local dist = getSpeakerDistance(senderName) if dist CHAT_RADIUS then return end local lowerMsg = message:lower() -- STOP COMMAND if lowerMsg:find("stop") then if isPlayingMusic then isPlayingMusic = false isVerityBusy = false if currentSongSound then currentSongSound:Stop() currentSongSound:Destroy() currentSongSound = nil end verityGuiText.Text = "" dialogueScreen.Text = "Verity: Music stopped!" task.delay(2, function() dialogueScreen.Text = "" end) return end end if isPlayingMusic then return end if isVerityBusy then return end if lowerMsg:find("play your favorite song") or lowerMsg:find("play your fav song") or lowerMsg:find("play my gal") or lowerMsg:find("play your theme") then addHistory(senderName, message) playFavoriteSong() return elseif lowerMsg:find("open youtube") or lowerMsg:find("youtube player") then isVerityBusy = true addHistory(senderName, message) triggerMusicPlayer() return end isVerityBusy = true addHistory(senderName, message) local speakerPlayer = Players:FindFirstChild(senderName) local joinDate = getPlayerContext(speakerPlayer) local hiddenNote = string.format( "[System Note: The person speaking to you right now is named '%s' (@%s). They joined Roblox on %s. Use this information naturally if they ask about themselves.]\n", speakerPlayer and speakerPlayer.DisplayName or senderName, senderName, joinDate ) local promptContext = hiddenNote .. message verityGuiText.Text = "..." dialogueScreen.Text = "Verity: Listening intently! ✨" verityFace.Texture = NORMAL_FACE task.spawn(function() local reply = askVerity(promptContext) addHistory("Verity", reply) verityGuiText.Text = "..." dialogueScreen.Text = "Verity: Generating voice! 🗣️" local sound = getFishAudioSound(reply, verityPart) verityGuiText.Text = reply dialogueScreen.Text = "Verity: " .. reply verityFace.Texture = TALKING_FACE if sound then sound:Play() end -- FIX: Only send to public chat if it's a real response, not an error fallback -- The askVerity function now always returns a proper response, so this is safe sendToPublicChat(reply) local waitTime = math.max(3, (#reply / 15) + 1.5) task.wait(waitTime) if verityPart and not isPlayingMusic then verityGuiText.Text = ""; dialogueScreen.Text = ""; verityFace.Texture = NORMAL_FACE end isVerityBusy = false end) end -- Hooking into Roblox Chat if TextChatService.ChatVersion == Enum.ChatVersion.TextChatService then TextChatService.MessageReceived:Connect(function(textChatMessage) if textChatMessage.TextSource then onPublicMessage(textChatMessage.Text, textChatMessage.TextSource.Name) end end) else local chatEvents = ReplicatedStorage:WaitForChild("DefaultChatSystemChatEvents", 2) if chatEvents then chatEvents:WaitForChild("OnMessageDoneFiltering").OnClientEvent:Connect(function(msgData) onPublicMessage(msgData.Message, msgData.FromSpeaker) end) end end -- DEATH SYSTEM local spawnVerity local function verityDie() if isRespawning then return end isRespawning = true isHeld = false dropButton.Visible = false if holdAnimTrack then holdAnimTrack:Stop(); holdAnimTrack:Destroy(); holdAnimTrack = nil end local char = LocalPlayer.Character or LocalPlayer.CharacterAdded:Wait() local root = char:WaitForChild("HumanoidRootPart") local respawnPos = root.Position - (root.CFrame.LookVector * 5) + Vector3.new(0, 3, 0) if verityPart and verityPart.Parent then verityPart.CFrame = CFrame.new(respawnPos) verityPart.AssemblyLinearVelocity = Vector3.new(0,0,0) verityPart.AssemblyAngularVelocity = Vector3.new(0,0,0) task.spawn(function() local madText = "Whoaa! What a wild ride! I'm back, but let's try not to do that again, alright?!" local sound = getFishAudioSound(madText, verityPart) verityGuiText.Text = madText dialogueScreen.Text = "Verity: " .. madText verityFace.Texture = TALKING_FACE if sound then sound:Play() end table.insert(conversationHistory, {role = "system", content = "The user just dropped you into the void or a kill block! You respawned behind them."}) table.insert(conversationHistory, {role = "assistant", content = madText}) local waitTime = math.max(3, (#madText / 15) + 1.5) task.wait(waitTime) if verityPart then verityFace.Texture = NORMAL_FACE; verityGuiText.Text = ""; dialogueScreen.Text = "" end isRespawning = false end) else spawnVerity(respawnPos, true) end end -- SPAWN function spawnVerity(pos, isRespawnCall) if verityPart and verityPart.Parent then verityPart:Destroy() end verityPart = Instance.new("Part", workspace) verityPart.Name = "VerityHead"; verityPart.Shape = Enum.PartType.Ball; verityPart.Size = Vector3.new(1.2, 1.2, 1.2); verityPart.Color = COLOR_VERITY; verityPart.Position = pos + Vector3.new(0, 6, 0) verityPart.Material = Enum.Material.SmoothPlastic verityPart.TopSurface = Enum.SurfaceType.Smooth; verityPart.BottomSurface = Enum.SurfaceType.Smooth verityPart.FrontSurface = Enum.SurfaceType.Smooth; verityPart.BackSurface = Enum.SurfaceType.Smooth verityPart.LeftSurface = Enum.SurfaceType.Smooth; verityPart.RightSurface = Enum.SurfaceType.Smooth verityMesh = Instance.new("SpecialMesh", verityPart); verityMesh.MeshType = Enum.MeshType.Sphere verityFace = Instance.new("Decal", verityPart); verityFace.Texture = NORMAL_FACE verityGui = Instance.new("BillboardGui", verityPart); verityGui.Size = UDim2.new(8, 0, 2, 0); verityGui.AlwaysOnTop = true verityGuiText = Instance.new("TextLabel", verityGui); verityGuiText.Size = UDim2.new(1, 0, 1, 0); verityGuiText.BackgroundTransparency = 1; verityGuiText.TextScaled = true; verityGuiText.TextColor3 = Color3.new(1, 1, 0) verityPart.Touched:Connect(function(hit) local name = hit.Name:lower() if name:find("kill") or name:find("lava") or name:find("death") or name:find("acid") then verityDie() end end) local cd = Instance.new("ClickDetector", verityPart) cd.MaxActivationDistance = 50 cd.MouseClick:Connect(function() if not isHeld then isHeld = true dropButton.Visible = true local char = LocalPlayer.Character local hum = char and char:FindFirstChild("Humanoid") local animator = hum and (hum:FindFirstChild("Animator") or Instance.new("Animator", hum)) if animator then local anim = Instance.new("Animation") anim.AnimationId = hum.RigType == Enum.HumanoidRigType.R15 and "rbxassetid://507768375" or "rbxassetid://182393478" holdAnimTrack = animator:LoadAnimation(anim) holdAnimTrack.Priority = Enum.AnimationPriority.Action holdAnimTrack:Play() end end end) if isRespawnCall then hasIntroduced = true task.spawn(function() local madText = "Whoaa! What a wild ride! I'm back, but let's try not to do that again, alright?!" local sound = getFishAudioSound(madText, verityPart) verityGuiText.Text = madText dialogueScreen.Text = "Verity: " .. madText verityFace.Texture = TALKING_FACE if sound then sound:Play() end table.insert(conversationHistory, {role = "system", content = "The user just dropped you into the void or a kill block! You respawned behind them."}) table.insert(conversationHistory, {role = "assistant", content = madText}) local waitTime = math.max(3, (#madText / 15) + 1.5) task.wait(waitTime) if verityPart then verityFace.Texture = NORMAL_FACE; verityGuiText.Text = ""; dialogueScreen.Text = "" end isRespawning = false end) end end -- MAIN LOOP RunService.RenderStepped:Connect(function(dt) if not verityPart or not verityPart.Parent then return end if verityPart.Position.Y = -1 then local impactForce = math.clamp(-lastYVelocity * 1.5, 10, 32) sizeSpring.velocity = Vector3.new(impactForce * 0.8, -impactForce * 1.0, impactForce * 0.8) verityPart.AssemblyLinearVelocity = Vector3.new(verityPart.AssemblyLinearVelocity.X, -lastYVelocity * 0.6, verityPart.AssemblyLinearVelocity.Z) end lastYVelocity = currentYVelocity end if verityFace.Texture == TALKING_FACE then local stretchFactor = 1 + (math.sin(tick() * 15) * 0.15) sizeSpring.target = Vector3.new(1.2 * (1/stretchFactor), 1.2 * stretchFactor, 1.2 * (1/stretchFactor)) else sizeSpring.target = Vector3.new(1.2, 1.2, 1.2) end local springForce = (sizeSpring.target - sizeSpring.current) * sizeSpring.stiffness sizeSpring.velocity = sizeSpring.velocity + (springForce - sizeSpring.velocity * sizeSpring.damping) * dt sizeSpring.current = sizeSpring.current + sizeSpring.velocity * dt verityMesh.Scale = Vector3.new(math.max(sizeSpring.current.X, 0.4)/1.2, math.max(sizeSpring.current.Y, 0.75)/1.2, math.max(sizeSpring.current.Z, 0.4)/1.2) if not hasIntroduced and verityPart.AssemblyLinearVelocity.Magnitude = 3 then local spawnPos = box.Position box:Destroy() spawnVerity(spawnPos, false) end end)