
KeylessUniversal

-- Delta Fixed: 100% Mathematically Accurate Classic Sonic Engine
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local player = Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")
local rootPart = character:WaitForChild("HumanoidRootPart")
-- 1:1 SONIC RETRO PHYSICS GUIDE SETTINGS
local ACCELERATION_STEP = 0.45 -- Precise, fixed buildup increment per frame
local NATURAL_FRICTION = 0.965 -- Slippery classic ground drift deceleration
local BALL_ROLL_DECEL = 0.992 -- Slippery sliding friction multiplier
local RETRO_RUN_CAP = 34.0 -- Precise 6 pixels per frame flat-ground ceiling
local SPINDASH_LAUNCH = 90.0 -- Explosive release velocity
local RETRO_JUMP = 72.0 -- Classic pixel-height jump arc
-- Internal Physics States
local currentMomentum = 16.0
local isSpindashing = false
local isRollingBall = false
local spinDegrees = 0
-- Configure baseline properties securely
humanoid.UseJumpPower = true
humanoid.JumpPower = RETRO_JUMP
humanoid.WalkSpeed = 0.1 -- Disable native ground handling to stop instant speed overrides
-- BUILD MOBILE HUD OVERLAY
local ScreenGui = Instance.new("ScreenGui", player:WaitForChild("PlayerGui"))
ScreenGui.ResetOnSpawn = false
local function buildTouchButton(text, pos, color)
local btn = Instance.new("TextButton", ScreenGui)
btn.Text = text
btn.Position = pos
btn.Size = UDim2.new(0, 120, 0, 45)
btn.BackgroundColor3 = color
btn.TextColor3 = Color3.fromRGB(255, 255, 255)
btn.Font = Enum.Font.SourceSansBold
btn.TextSize = 15
Instance.new("UICorner", btn).CornerRadius = UDim.new(0, 10)
return btn
end
local SpindashBtn = buildTouchButton("SPINDASH", UDim2.new(0.70, 0, 0.50, 0), Color3.fromRGB(0, 110, 220))
-- EXECUTOR-SAFE PHYSICS DRIVER (Bypasses Humanoid velocity clamping loops)
local physicsMotor = rootPart:FindFirstChild("SonicBypassForce") or Instance.new("BodyVelocity", rootPart)
physicsMotor.Name = "SonicBypassForce"
physicsMotor.MaxForce = Vector3.new(45000, 0, 45000) -- Leaves Y free so jumping handles natively
physicsMotor.Velocity = Vector3.new(0,0,0)
-- Container for the visual model sphere
local visualSpinSphere = nil
-- RETRO VISUAL GENERATOR
local function deleteSpinBall()
if visualSpinSphere then
visualSpinSphere:Destroy()
visualSpinSphere = nil
end
for _, part in pairs(character:GetChildren()) do
if part:IsA("BasePart") and part.Name ~= "HumanoidRootPart" then
part.Transparency = 0
end
end
if character:FindFirstChild("Animate") and not character.Animate.Enabled then
character.Animate.Enabled = true
end
end
local function spawnSpinBall()
deleteSpinBall()
local targetColor = Color3.fromRGB(0, 100, 255)
local headPart = character:FindFirstChild("Head")
if headPart and headPart:IsA("BasePart") then targetColor = headPart.Color end
for _, part in pairs(character:GetChildren()) do
if part:IsA("BasePart") and part.Name ~= "HumanoidRootPart" then part.Transparency = 1 end
end
if character:FindFirstChild("Animate") and character.Animate.Enabled then character.Animate.Enabled = false end
local sphere = Instance.new("Part")
sphere.Name = "SonicSpinSphere"
sphere.Size = Vector3.new(3.8, 3.8, 3.8)
sphere.Shape = Enum.PartType.Ball
sphere.Color = targetColor
sphere.Material = Enum.Material.Neon
sphere.CanCollide = false
sphere.Parent = character
local weld = Instance.new("Weld")
weld.Name = "SpinWeldObject"
weld.Part0 = rootPart
weld.Part1 = sphere
weld.C0 = CFrame.new(0, -0.4, 0)
weld.Parent = sphere
visualSpinSphere = sphere
end
-- TRACK AIRBORNE AND LANDED STATUS CHANGES
humanoid.StateChanged:Connect(function(_, newState)
if newState == Enum.HumanoidStateType.Freefall or newState == Enum.HumanoidStateType.Jumping then
isRollingBall = true
spawnSpinBall()
elseif newState == Enum.HumanoidStateType.Landed then
if isRollingBall then
isRollingBall = false
deleteSpinBall()
end
end
end)
-- CORE RETRO STEP PHYSICS RUNNER LOOP
RunService.Heartbeat:Connect(function(deltaTime)
if not character or not rootPart or not humanoid or not physicsMotor then return end
local flatVelocity = Vector3.new(rootPart.AssemblyLinearVelocity.X, 0, rootPart.AssemblyLinearVelocity.Z).Magnitude
-- Clean rolling state exit upon dropping below floor limits
if isRollingBall and flatVelocity < 4 and not isSpindashing and humanoid.FloorMaterial ~= Enum.Material.Air then
isRollingBall = false
deleteSpinBall()
physicsMotor.Velocity = Vector3.new(0, 0, 0)
end
-- ROTATE GEOMETRIC SPHERE
if (isRollingBall or isSpindashing) and visualSpinSphere then
local weld = visualSpinSphere:FindFirstChild("SpinWeldObject")
if weld then
local speedMultiplier = (flatVelocity < 5) and 180 or (flatVelocity + 45) * 35
spinDegrees = (spinDegrees + (deltaTime * speedMultiplier)) % 360
weld.C0 = CFrame.new(0, -0.4, 0) * CFrame.Angles(math.rad(-spinDegrees), 0, 0)
end
end
-- ABSOLUTE FREEZE CONSTRAINT DURING SPINDASH CHARGING (Blocks joystick movement completely)
if isSpindashing then
rootPart.AssemblyLinearVelocity = Vector3.new(0, rootPart.AssemblyLinearVelocity.Y, 0)
physicsMotor.Velocity = Vector3.new(0, 0, 0)
return
end
-- READ JOYSTICK VECTOR FOR CUSTOM MOMENTUM CALCULATION
local thumbstickInput = humanoid.MoveDirection
if thumbstickInput.Magnitude > 0.05 then
if isRollingBall then
-- Low Friction Slidings: Keeps rolling momentum drifting smoothly
currentMomentum = math.max(16, currentMomentum * (BALL_ROLL_DECEL ^ (deltaTime * 60)))
physicsMotor.Velocity = rootPart.CFrame.LookVector * currentMomentum
else
-- FIXED ACCELERATION STEP: Gradually builds up velocity the longer you hold forward
if currentMomentum < RETRO_RUN_CAP then
currentMomentum = math.min(RETRO_RUN_CAP, currentMomentum + (ACCELERATION_STEP * deltaTime * 60))
else
-- Slow down gradually if launched over the running limit via a Spindash
currentMomentum = math.max(RETRO_RUN_CAP, currentMomentum - (0.25 * deltaTime * 60))
end
physicsMotor.Velocity = thumbstickInput * currentMomentum
end
-- Smooth turning vector orientation mapping
rootPart.CFrame = CFrame.new(rootPart.Position, rootPart.Position + Vector3.new(thumbstickInput.X, 0, thumbstickInput.Z))
else
-- Slippery friction decay coefficient when letting go of the stick
currentMomentum = math.max(0, currentMomentum * (NATURAL_FRICTION ^ (deltaTime * 60)))
if currentMomentum <= 1 then
physicsMotor.Velocity = Vector3.new(0, 0, 0)
else
local driftHeading = rootPart.CFrame.LookVector
physicsMotor.Velocity = Vector3.new(driftHeading.X * currentMomentum, 0, driftHeading.Z * currentMomentum)
end
end
end)
-- BUTTON CONNECTIONS USING EXECUTOR-SAFE MOBILE TOUCH TRIGGERS
SpindashBtn.InputBegan:Connect(function(input)
if input.UserInputType == Enum.UserInputType.Touch or input.UserInputType == Enum.UserInputType.MouseButton1 then
local flatVelocity = Vector3.new(rootPart.AssemblyLinearVelocity.X, 0, rootPart.AssemblyLinearVelocity.Z).Magnitude
if flatVelocity > 10 and humanoid.FloorMaterial ~= Enum.Material.Air then
-- MID-RUN BALL ROLL
isRollingBall = not isRollingBall
if isRollingBall then
currentMomentum = flatVelocity
spawnSpinBall()
SpindashBtn.BackgroundColor3 = Color3.fromRGB(0, 220, 220)
else
deleteSpinBall()
SpindashBtn.BackgroundColor3 = Color3.fromRGB(0, 110, 220)
end
elseif flatVelocity <= 10 then
-- STATIC CHARGE SPINDASH: Locks position immediately
isSpindashing = true
spawnSpinBall()
SpindashBtn.BackgroundColor3 = Color3.fromRGB(230, 40, 40)
end
end
end)
SpindashBtn.InputEnded:Connect(function(input)
if input.UserInputType == Enum.UserInputType.Touch or input.UserInputType == Enum.UserInputType.MouseButton1 then
if not isSpindashing then return end
isSpindashing = false
SpindashBtn.BackgroundColor3 = Color3.fromRGB(0, 110, 220)
-- EXPLOSIVE PROPULSION BLAST: Forced high-velocity forward vector release
currentMomentum = SPINDASH_LAUNCH
local launchHeading = rootPart.CFrame.LookVector
rootPart.AssemblyLinearVelocity = Vector3.new(launchHeading.X * currentMomentum, rootPart.AssemblyLinearVelocity.Y, launchHeading.Z * currentMomentum)
physicsMotor.Velocity = Vector3.new(launchHeading.X * currentMomentum, 0, launchHeading.Z * currentMomentum)
isRollingBall = true
end
end)
-- Cleanup UI sequences upon character death
humanoid.Died:Connect(function()
deleteSpinBall()
if physicsMotor then physicsMotor:Destroy() end
ScreenGui:Destroy()
end)



I am mad slow can you make it faster