-- Nextbot Chase Script with Enhanced Movement and Obstacle Avoidance

local nextbot = script.Parent

-- Configuration variables
local acceleration = 70         -- Maximum acceleration rate
local maxSpeed = 60             -- Maximum speed
local detectionRadius = 1500    -- Detection radius for players
local updateInterval = 0.1      -- Update interval in seconds
local groundOffset = 6          -- Offset above the ground
local slowdownDistance = 10     -- Distance within which the Nextbot slows down near the player
local obstacleAvoidanceDistance = 5 -- Distance to look ahead for obstacles

local velocity = Vector3.new(0, 0, 0)

local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local TweenService = game:GetService("TweenService")

local currentTween = nil

-- Function to find the nearest player
local function findNearestPlayer()
	local nearestPlayer = nil
	local shortestDistance = detectionRadius

	for _, player in pairs(Players:GetPlayers()) do
		local character = player.Character
		if character and character.PrimaryPart then
			local distance = (character.PrimaryPart.Position - nextbot.Position).Magnitude
			if distance < shortestDistance then
				shortestDistance = distance
				nearestPlayer = character
			end
		end
	end
	return nearestPlayer
end

-- Function to get the ground Y position
local function getGroundPosition(position)
	local rayOrigin = Vector3.new(position.X, position.Y + 50, position.Z)
	local rayDirection = Vector3.new(0, -1000, 0)

	local raycastParams = RaycastParams.new()
	-- Ignore Nextbot, players, and characters
	local ignoreList = {nextbot}
	for _, player in pairs(Players:GetPlayers()) do
		if player.Character then
			table.insert(ignoreList, player.Character)
		end
	end
	raycastParams.FilterDescendantsInstances = ignoreList
	raycastParams.FilterType = Enum.RaycastFilterType.Blacklist

	local result = workspace:Raycast(rayOrigin, rayDirection, raycastParams)
	if result then
		return result.Position.Y + groundOffset
	else
		return nextbot.Position.Y
	end
end

-- Function for obstacle avoidance
local function avoidObstacles(desiredVelocity)
	local rayOrigin = nextbot.Position
	local rayDirection = desiredVelocity.Unit * obstacleAvoidanceDistance

	local raycastParams = RaycastParams.new()
	-- Ignore Nextbot itself
	raycastParams.FilterDescendantsInstances = {nextbot}
	raycastParams.FilterType = Enum.RaycastFilterType.Blacklist

	local result = workspace:Raycast(rayOrigin, rayDirection, raycastParams)
	if result then
		-- Calculate a steering vector to avoid the obstacle
		local normal = result.Normal
		local avoidanceForce = result.Normal * acceleration
		-- Adjust desired velocity to avoid obstacle
		desiredVelocity = desiredVelocity + avoidanceForce
	end

	return desiredVelocity
end

-- Main update loop
local lastUpdateTime = os.clock()
RunService.Stepped:Connect(function(time, deltaTime)
	local currentTime = os.clock()
	local elapsedTime = currentTime - lastUpdateTime
	if elapsedTime >= updateInterval then
		lastUpdateTime = currentTime

		local target = findNearestPlayer()
		if target and target.PrimaryPart then
			local targetPosition = target.PrimaryPart.Position
			local distanceToTarget = (targetPosition - nextbot.Position).Magnitude

			-- Slow down near the player
			local speedFactor = 1
			if distanceToTarget < slowdownDistance then
				speedFactor = distanceToTarget / slowdownDistance
			end

			local currentMaxSpeed = maxSpeed * speedFactor
			local currentAcceleration = acceleration * speedFactor

			-- Desired velocity towards the target
			local desiredVelocity = (targetPosition - nextbot.Position).Unit * currentMaxSpeed
			desiredVelocity = Vector3.new(desiredVelocity.X, 0, desiredVelocity.Z)

			-- Obstacle avoidance
			desiredVelocity = avoidObstacles(desiredVelocity)

			-- Steering towards desired velocity
			local steering = desiredVelocity - velocity
			if steering.Magnitude > currentAcceleration then
				steering = steering.Unit * currentAcceleration
			end

			-- Update velocity
			velocity = velocity + steering * updateInterval
			if velocity.Magnitude > currentMaxSpeed then
				velocity = velocity.Unit * currentMaxSpeed
			end

			-- Compute new position
			local newPosition = nextbot.Position + velocity * updateInterval
			local groundY = getGroundPosition(newPosition)
			newPosition = Vector3.new(newPosition.X, groundY, newPosition.Z)

			-- Move the Nextbot using TweenService
			if currentTween then
				currentTween:Cancel()
			end
			local tweenInfo = TweenInfo.new(
				updateInterval,
				Enum.EasingStyle.Linear
			)
			local tween = TweenService:Create(nextbot, tweenInfo, {Position = newPosition})
			currentTween = tween
			tween:Play()

			-- Update orientation
			if velocity.Magnitude > 0.1 then
				local lookAt = nextbot.Position + velocity
				nextbot.CFrame = CFrame.new(nextbot.Position, lookAt)
			end

		else
			-- No target found, gradually slow down
			local currentAcceleration = acceleration
			local steering = -velocity
			if steering.Magnitude > currentAcceleration then
				steering = steering.Unit * currentAcceleration
			end

			velocity = velocity + steering * updateInterval

			if velocity.Magnitude > 0.1 then
				if velocity.Magnitude > maxSpeed then
					velocity = velocity.Unit * maxSpeed
				end

				local newPosition = nextbot.Position + velocity * updateInterval
				local groundY = getGroundPosition(newPosition)
				newPosition = Vector3.new(newPosition.X, groundY, newPosition.Z)

				if currentTween then
					currentTween:Cancel()
				end
				local tweenInfo = TweenInfo.new(
					updateInterval,
					Enum.EasingStyle.Linear
				)
				local tween = TweenService:Create(nextbot, tweenInfo, {Position = newPosition})
				currentTween = tween
				tween:Play()

				if velocity.Magnitude > 0.1 then
					local lookAt = nextbot.Position + velocity
					nextbot.CFrame = CFrame.new(nextbot.Position, lookAt)
				end
			else
				velocity = Vector3.new(0, 0, 0)
			end
		end
	end
end)

remove obstacle avoidance.. make the slowdown be a speedup when player near, and enhance the script