local SPEED = 190 -- Fallback horizontal speed on foot in studs per second. local SPEED_MIN = 260 -- Minimum sinusoidal speed in studs per second. local SPEED_MAX = 265 -- Maximum sinusoidal speed in studs per second. local SPEED_PERIOD = 0.2 -- Complete sinusoidal cycle period in seconds (5 Hz). local EFFECTIVE_AVG_SPEED = (SPEED_MAX + SPEED_MIN) * 0.5 -- 265 studs/s nominal average local BOAT_ACCELERATION = 140 local BOAT_PURCHASE_RANGE = 450 local BOAT_APPROACH_RANGE = 420 -- Margin for dealer position offsets. local MIN_ROOT_Y = 2.0 -- Strict altitude floor (keeps boat above waterline at all times). local MAX_TRAVEL_SECONDS = 180 local LOAD_UI = true local SHOW_ROUTE_TRACERS = true local REWARD_SEA = 1 -- Set to 1, 2, or 3 for your current Sea. local ESTIMATED_PICKUP_SECONDS = 0.03 local LOOKAHEAD_STOPS = 4 -- 100x100x100 Geometry & Cluster Fusion Parameters local HITBOX_HALF_EXTENT = 42 -- 50 studs radius minus 8-stud safety registration buffer local CLUSTER_MERGE_DIST_H = 84 -- 42 + 42 studs horizontal overlap threshold local CLUSTER_MERGE_DIST_V = 80 -- Vertical overlap threshold local Players = game:GetService("Players") local RunService = game:GetService("RunService") local ReplicatedStorage = game:GetService("ReplicatedStorage") local player = Players.LocalPlayer assert(player, "Run on the client") -- Sinusoidal 3D Speed Generator (260 - 270 studs/s) Synchronized with Server Clock local function getSinusoidalSpeed() local mid = (SPEED_MAX + SPEED_MIN) * 0.5 -- 265 local amp = (SPEED_MAX - SPEED_MIN) * 0.5 -- 5 local omega = (2 * math.pi) / SPEED_PERIOD local serverTimeCycle = workspace:GetServerTimeNow() % SPEED_PERIOD return mid + amp * math.sin(serverTimeCycle * omega) end local C = { Speed = SPEED, BoatSpeed = EFFECTIVE_AVG_SPEED, MinRootY = MIN_ROOT_Y, ModelMatchRadius = 50, ModelMatchSeparation = 8, PollSeconds = 0.05, SweepMargin = 5, PendingConfirmSeconds = 3, CharacterTimeout = 15, ChestFailureCooldown = 10, MaxChestCooldown = 120, MatchRadius = 1, ObserveSeconds = 0.5, ReplanSeconds = 1, SwitchGain = 1.25, MinimumCommitSeconds = 1.5, FinishDistance = 30, BeamWidth = 8, BranchWidth = 8, PlanBudgetSeconds = 0.008, MaxRespawnWait = 0, OverdueGrace = 15, ObservationRadius = 200, UnknownInspectionDistance = 35, UnknownProbeCooldown = 60, ContestRadius = 160, MapRefreshSeconds = 0.5, Debug = true, } local gradeBySpawnName = {Chest1 = "Silver", Chest2 = "Gold", Chest3 = "Diamond"} local chestEconomy = { Silver = {respawn = 180, rewards = {{250, 420}, {500, 1000}, {1000, 1695}}}, Gold = {respawn = 360, rewards = {{600, 1100}, {2300, 3120}, {3875, 5200}}}, Diamond = {respawn = 720, rewards = {{1500, 3000}, {5000, 7250}, {8000, 12250}}}, } local function gradeOf(record) return gradeBySpawnName[record.name] or "Gold" end local function economyOf(record) return chestEconomy[gradeOf(record)] end local function respawnOf(record) return record.respawnEstimate or (gradeBySpawnName[record.name] and economyOf(record).respawn) end local function enforceAltitudeFloor(position) if position.Y >= C.MinRootY then return position end return Vector3.new(position.X, C.MinRootY, position.Z) end -- CALCULATED LEG SPEED TRACKER local legHistory = {} local maxLegHistory = 15 local avgLegSpeed = 0 local function recordLegPerformance(distance, timeTaken) if timeTaken <= 0.02 or distance <= 4.0 then return end local calculatedSpeed = distance / timeTaken table.insert(legHistory, calculatedSpeed) if #legHistory > maxLegHistory then table.remove(legHistory, 1) end local sum = 0 for _, s in ipairs(legHistory) do sum += s end avgLegSpeed = sum / #legHistory end -- ROUTE PLANNER (Direct 3D Euclidean Distance) local Planner = {} function Planner.travelSeconds(a, b, speed3D) local dist3D = (b - a).Magnitude return dist3D / speed3D end function Planner.sweepPath(node, fromPosition, margin) local center = Vector3.new(node.position.X, math.max(node.position.Y, C.MinRootY), node.position.Z) local delta = center - fromPosition local direction = delta.Magnitude > 0.001 and delta.Unit or Vector3.new(0, 0, -1) -- Graze outer boundary perimeter in 3D local entryPoint = center - direction * HITBOX_HALF_EXTENT local exitPoint = entryPoint + direction * (margin + 6) return enforceAltitudeFloor(entryPoint), center, enforceAltitudeFloor(exitPoint) end function Planner.leg(position, node, startAt, now, options) local entry, _, exit = Planner.sweepPath(node, position, options.sweepMargin) local travel = options.travelEstimator and options.travelEstimator(position, entry) or Planner.travelSeconds(position, entry, options.speed) if travel > options.maxTravel then return nil end travel = math.max(0.05, travel * options.travelFactor) local arrival = startAt + travel if node.predicted and arrival > node.readyAt + options.overdueGrace then return nil end local waitTime = math.max(0, node.readyAt - arrival, node.cooldown - arrival) if waitTime == math.huge or waitTime > options.maxWait then return nil end local finish = arrival + waitTime + options.service local exposed = math.max(0, finish - math.max(now, node.readyAt)) local probability = node.confidence * node.reliability * math.exp(-node.hazard * exposed) probability *= 1 - 0.35 * node.contest * math.min(1, travel / 2) return {seconds = finish - startAt, probability = math.clamp(probability, 0.02, 1), exitPosition = exit} end local function better(a, b) if math.abs(a.score - b.score) > 1e-9 then return a.score > b.score end if math.abs(a.elapsed - b.elapsed) > 1e-9 then return a.elapsed < b.elapsed end return a.first.id < b.first.id end local function keepBest(list, entry, limit) local index = #list + 1 for i, old in ipairs(list) do if better(entry, old) then index = i; break end end if index <= limit then table.insert(list, index, entry) if #list > limit then table.remove(list) end end end function Planner.plan(position, nodes, now, options, forcedFirstId) local beam = {{position = position, elapsed = 0, reward = 0, visited = {}, route = {}}} local best local deadline = options.budget and (workspace:GetServerTimeNow() + options.budget) for depth = 1, options.depth do local expanded = {} for _, state in ipairs(beam) do if depth > 1 and deadline and workspace:GetServerTimeNow() >= deadline then return best end local branches = {} for _, node in ipairs(nodes) do if not state.visited[node.id] and (depth > 1 or not forcedFirstId or node.id == forcedFirstId) then local leg = Planner.leg(state.position, node, now + state.elapsed, now, options) if leg then local elapsed = state.elapsed + leg.seconds local reward = state.reward + node.value * leg.probability local entry = { position = leg.exitPosition, first = state.first or node, elapsed = elapsed, reward = reward, score = reward / (elapsed + options.smoothing), parent = state, node = node, } keepBest(branches, entry, options.branch) end end end for _, entry in ipairs(branches) do entry.visited = table.clone(entry.parent.visited) entry.visited[entry.node.id] = true entry.route = table.clone(entry.parent.route) table.insert(entry.route, entry.node) entry.parent, entry.node = nil, nil keepBest(expanded, entry, options.width) if not best or better(entry, best) then best = entry end end end if #expanded == 0 then break end beam = expanded end return best end -- DEALER & BOAT CORE local dealerList, lastDealerScan = {}, -math.huge local ownedBoat = nil local function rememberDealer(npc) if not (npc:IsA("Model") or npc:IsA("BasePart")) or not npc.Name:lower():gsub("%s+", ""):find("boatdealer", 1, true) then return end local folder = workspace:FindFirstChild("NPCs") if not folder or not npc:IsDescendantOf(folder) then return end local position = npc:IsA("Model") and npc:GetPivot().Position or npc.Position for _, dealer in ipairs(dealerList) do if (dealer.position - position).Magnitude <= 5 then dealer.instance, dealer.position = npc, position return end end table.insert(dealerList, {instance = npc, position = position}) end local function scanDealers(force) local now = workspace:GetServerTimeNow() if not force and now - lastDealerScan < 5 then return end lastDealerScan = now for _, dealer in ipairs(dealerList) do if dealer.instance and not dealer.instance:IsDescendantOf(workspace) then dealer.instance = nil end end end local function boatSeat(boat) return boat and boat.Parent and (boat:FindFirstChild("VehicleSeat", true) or boat:FindFirstChildWhichIsA("VehicleSeat", true)) end local function boatBelongsToPlayer(boat) local seat = boatSeat(boat) if seat and seat.Occupant and seat.Occupant.Parent == player.Character then return true end local owner = boat:FindFirstChild("Owner", true) if not owner or not owner:IsA("ValueBase") then return false end local value = owner.Value return value == player or value == player.Name or value == player.UserId or tostring(value) == tostring(player.UserId) end -- CHARACTER & VELOCITY HELPERS local function parts() local char = player.Character local root = char and char:FindFirstChild("HumanoidRootPart") local hum = char and char:FindFirstChildOfClass("Humanoid") if char and char:IsDescendantOf(workspace) and root and hum and hum.Health > 0 then return char, root, hum end end local function getLiveVelocity() local char, root, hum = parts() if not char or not root then return 0 end if hum and hum.SeatPart and hum.SeatPart:IsA("VehicleSeat") then local motionPart = hum.SeatPart.AssemblyRootPart or hum.SeatPart local vel = motionPart.AssemblyLinearVelocity or motionPart.Velocity return vel.Magnitude else local vel = root.AssemblyLinearVelocity or root.Velocity return vel.Magnitude end end -- UI local playerGui = player:WaitForChild("PlayerGui", 10) local GUI_NAME = "ChestFarmerBoat" local globalEnvironment = getgenv and getgenv() or _G if globalEnvironment.ChestFarmerBoatStop then pcall(globalEnvironment.ChestFarmerBoatStop) end local oldGui = playerGui:FindFirstChild(GUI_NAME) if oldGui then oldGui:Destroy() end local gui = Instance.new("ScreenGui") gui.Name, gui.ResetOnSpawn = GUI_NAME, false if LOAD_UI then gui.Parent = playerGui end local panel = Instance.new("Frame") panel.Size = UDim2.fromOffset(300, 168) panel.Position = UDim2.fromOffset(15, 100) panel.BackgroundColor3 = Color3.fromRGB(25, 28, 34) panel.BorderSizePixel = 0 panel.Parent = gui local corner = Instance.new("UICorner") corner.CornerRadius = UDim.new(0, 10) corner.Parent = panel local panelScale = Instance.new("UIScale") panelScale.Parent = panel local function label(text, x, y, width, height, size, color) local item = Instance.new("TextLabel") item.BackgroundTransparency = 1 item.Position = UDim2.fromOffset(x, y) item.Size = UDim2.fromOffset(width, height) item.Font = Enum.Font.Gotham item.TextSize = size item.TextColor3 = color item.TextXAlignment = Enum.TextXAlignment.Left item.TextTruncate = Enum.TextTruncate.AtEnd item.Text = text item.Parent = panel return item end local light = Color3.fromRGB(240, 242, 245) local muted = Color3.fromRGB(160, 167, 178) label("Chest farm · 100% Boat", 14, 10, 190, 26, 16, light) label("Money gained", 14, 46, 130, 18, 11, muted) label("Money / min", 157, 46, 130, 18, 11, muted) local gainedLabel = label("—", 14, 65, 130, 24, 18, Color3.fromRGB(125, 225, 163)) local rateLabel = label("—", 157, 65, 130, 24, 18, light) label("Live velocity", 14, 95, 130, 18, 11, muted) label("Avg leg speed", 157, 95, 130, 18, 11, muted) local speedLabel = label("0.0 studs/s", 14, 114, 130, 22, 14, Color3.fromRGB(80, 200, 255)) local avgSpeedLabel = label("—", 157, 114, 130, 22, 14, Color3.fromRGB(125, 225, 163)) local statusLabel = label("Starting…", 14, 142, 272, 17, 11, muted) local stopButton = Instance.new("TextButton") stopButton.Size = UDim2.fromOffset(60, 26) stopButton.Position = UDim2.fromOffset(226, 10) stopButton.Text = "Stop" stopButton.Font = Enum.Font.Gotham stopButton.TextSize = 12 stopButton.TextColor3 = light stopButton.BackgroundColor3 = Color3.fromRGB(55, 60, 70) stopButton.BorderSizePixel = 0 stopButton.Parent = panel local buttonCorner = Instance.new("UICorner") buttonCorner.CornerRadius = UDim.new(0, 6) buttonCorner.Parent = stopButton local stopped = false local connections = {} local virtualUser = game:GetService("VirtualUser") local antiAfkConnection = player.Idled:Connect(function() virtualUser:CaptureController() virtualUser:ClickButton2(Vector2.new()) end) table.insert(connections, antiAfkConnection) local candidates, records = {}, {} local firstCollectedRecord = nil local currentTarget local currentRouteDestination local currentTargetBoxCenter = nil local timing = {travelFactor = 1, service = ESTIMATED_PICKUP_SECONDS} local lastObserved = -math.huge local function log(message) if C.Debug then print("[Chest Farmer Boat] " .. message) end end local function display(message) if gui.Parent then statusLabel.Text = message end end local startingBeli, moneyStarted local function formatMoney(value) local rounded = math.floor(math.abs(value) + 0.5) local digits = string.format("%.0f", rounded) local grouped = digits:reverse():gsub("(%d%d%d)", "%1,"):reverse():gsub("^,", "") return (value < 0 and rounded > 0 and "-$" or "$") .. grouped end local function readBeli() local data = player:FindFirstChild("Data") local value = data and data:FindFirstChild("Beli") if value and (value:IsA("IntValue") or value:IsA("NumberValue")) then return value.Value end end local function updateMoney() if not gui.Parent then return end local balance = readBeli() if not balance then return end local now = workspace:GetServerTimeNow() if startingBeli == nil then startingBeli, moneyStarted = balance, now end local gained = balance - startingBeli local elapsed = now - moneyStarted gainedLabel.Text = formatMoney(gained) rateLabel.Text = formatMoney(elapsed > 0 and gained * 60 / elapsed or 0) end table.insert(connections, RunService.Heartbeat:Connect(function() updateMoney() if gui.Parent then local vel = getLiveVelocity() speedLabel.Text = string.format("%.1f studs/s", vel) if avgLegSpeed > 0 then avgSpeedLabel.Text = string.format("%.1f studs/s", avgLegSpeed) else avgSpeedLabel.Text = "—" end end end)) local function stop() if stopped then return end stopped = true display("Stopping farm…") end globalEnvironment.ChestFarmerBoatStop = stop table.insert(connections, stopButton.MouseButton1Click:Connect(stop)) table.insert(connections, gui.Destroying:Connect(stop)) local function waitCharacter(timeout) local deadline = workspace:GetServerTimeNow() + timeout repeat local char, root, hum = parts() if char then return char, root, hum end task.wait(C.PollSeconds) until stopped or workspace:GetServerTimeNow() >= deadline end local function available(part) return part and part:IsDescendantOf(workspace) and part:FindFirstChild("TouchInterest") ~= nil end local function track(obj) rememberDealer(obj) if not obj:IsA("BasePart") or not obj.Name:lower():find("chest", 1, true) then return end local visualFolder = workspace:FindFirstChild("ChestModels") if visualFolder and obj:IsDescendantOf(visualFolder) then return end pcall(function() obj.Size = Vector3.new(100, 100, 100) obj.CanCollide = false end) if candidates[obj] == nil then candidates[obj] = true end end table.insert(connections, workspace.DescendantAdded:Connect(track)) task.spawn(function() local pending = {workspace} while not stopped and #pending > 0 do for _ = 1, 200 do local item = table.remove(pending) if not item then break end track(item) for _, child in ipairs(item:GetChildren()) do table.insert(pending, child) end end task.wait() end end) -- REWARDS & COOLDOWNS (Server-Synchronized) local function markEmpty(record, now, ours) if record.state == "empty" and record.emptyAt and now - record.emptyAt < 5 then return end record.emptyAt = now record.readyAt = now + (respawnOf(record) or 180) record.observationGap = false record.state = "empty" record.lastLossCounted = not ours if not ours then record.otherLosses = (record.otherLosses or 0) + 1 end end local pendingAttempts = {} local lastPickupBalance = readBeli() local function beginPending(record, sweepSeconds) if record.pendingAttempt then return record.pendingAttempt end local now = workspace:GetServerTimeNow() local attempt = {record = record, expires = now + sweepSeconds + C.PendingConfirmSeconds + 1, crossed = false} record.pendingAttempt = attempt record.pendingUntil = attempt.expires table.insert(pendingAttempts, attempt) return attempt end table.insert(connections, RunService.Heartbeat:Connect(function() local now, balance = workspace:GetServerTimeNow(), readBeli() if balance and lastPickupBalance and balance > lastPickupBalance then local oldest for _, attempt in ipairs(pendingAttempts) do if not attempt.done and now <= attempt.expires then oldest = attempt break end end if oldest then oldest.done = true local record = oldest.record if not firstCollectedRecord then firstCollectedRecord = record end markEmpty(record, now, true) record.collected = true record.successes = (record.successes or 0) + 1 record.failures = 0 record.cooldown = now + 1 log("Beli confirmed for " .. record.name) end end if balance then lastPickupBalance = balance end for i = #pendingAttempts, 1, -1 do local attempt = pendingAttempts[i] if attempt.done or now >= attempt.expires then local record = attempt.record if record.pendingAttempt == attempt then record.pendingAttempt, record.pendingUntil = nil, nil if not attempt.done and attempt.crossed and available(record.part) then record.misses = (record.misses or 0) + 1 record.failures = (record.failures or 0) + 1 record.cooldown = now + math.min(C.MaxChestCooldown, C.ChestFailureCooldown * 2 ^ math.min(record.failures - 1, 4)) end end table.remove(pendingAttempts, i) end end end)) local function refreshChests(force) local now = workspace:GetServerTimeNow() if not force and now - lastObserved < C.ObserveSeconds then return end lastObserved = now for _, r in ipairs(records) do r.spawnPart = nil; r.part = nil end for part in pairs(candidates) do if not part:IsDescendantOf(workspace) then candidates[part] = nil else pcall(function() if part.Size.X < 90 then part.Size = Vector3.new(100, 100, 100) part.CanCollide = false end end) local r = candidates[part] if r == true then r = nil for _, existing in ipairs(records) do if existing.name == part.Name and (existing.position - part.Position).Magnitude <= C.MatchRadius then r = existing break end end if not r then r = {id = #records + 1, name = part.Name, position = part.Position, cooldown = 0, failures = 0, successes = 0, misses = 0, exposure = 0, otherLosses = 0, state = "unknown"} table.insert(records, r) end candidates[part] = r end r.spawnPart = part if available(part) then r.part = part end r.position = part.Position end end local _, root = parts() for _, r in ipairs(records) do local wasReady = r.state == "ready" local rawReady = available(r.part) if rawReady then r.state, r.collected = "ready", false r.emptyAt = nil r.readyAt = now else local nearby = root and (root.Position - r.position).Magnitude <= C.ObservationRadius if r.spawnPart ~= nil or nearby or not workspace.StreamingEnabled then if wasReady then markEmpty(r, now, false) end r.state = "empty" else r.state = "unknown" end end end end -- FALLBACK WALKING MOVEMENT (Only used when acquiring initial boat) local function approachPosition(target, stopRadius) local char, root, hum = parts() if not char then return false end target = enforceAltitudeFloor(target) local attachment = Instance.new("Attachment", root) local drive = Instance.new("LinearVelocity", root) drive.Attachment0 = attachment drive.RelativeTo = Enum.ActuatorRelativeTo.World drive.ForceLimitsEnabled = false local noclipConn = RunService.Stepped:Connect(function() for _, p in ipairs(char:GetDescendants()) do if p:IsA("BasePart") then p.CanCollide = false end end end) local estimate = Planner.travelSeconds(root.Position, target, C.Speed) local began = workspace:GetServerTimeNow() local arrived = false while not stopped and player.Character == char and hum.Health > 0 and workspace:GetServerTimeNow() - began <= estimate * 2 + 3 do RunService.Heartbeat:Wait() local delta = target - root.Position if delta.Magnitude <= stopRadius then arrived = true; break end drive.VectorVelocity = delta.Unit * C.Speed end noclipConn:Disconnect() drive:Destroy() attachment:Destroy() return arrived end local function buyDinghy() local boats = workspace:FindFirstChild("Boats") or workspace:WaitForChild("Boats", 3) local remoteFolder = ReplicatedStorage:FindFirstChild("Remotes") local event = remoteFolder and remoteFolder:FindFirstChild("CommF_") if not boats or not event then return nil end local _, root = parts() for _, existing in ipairs(boats:GetChildren()) do local seat = boatSeat(existing) if seat and root and boatBelongsToPlayer(existing) and (root.Position - seat.Position).Magnitude <= 500 then return existing end end local seen = {} for _, child in ipairs(boats:GetChildren()) do seen[child] = true end local arrivals = {} local added = boats.ChildAdded:Connect(function(child) table.insert(arrivals, child) end) task.spawn(function() pcall(function() event:InvokeServer("BuyBoat", "Dinghy") end) end) local deadline = workspace:GetServerTimeNow() + 8 local found repeat for _, boat in ipairs(arrivals) do if boat.Parent == boats and not seen[boat] and boatBelongsToPlayer(boat) and boatSeat(boat) then found = boat break end end if found then break end task.wait(0.1) until stopped or workspace:GetServerTimeNow() >= deadline added:Disconnect() return found end local function boardBoat(boat) local char, root, hum = parts() local seat = boatSeat(boat) if not char or not seat then return false end seat:Sit(hum) local deadline = workspace:GetServerTimeNow() + 2 while not stopped and workspace:GetServerTimeNow() < deadline and seat.Occupant ~= hum do task.wait(0.05) end return seat.Occupant == hum end local function ensureSeatedInBoat() local char, root, hum = parts() if not char then return nil, nil end if hum.SeatPart and hum.SeatPart:IsA("VehicleSeat") then local boat = hum.SeatPart:FindFirstAncestorOfClass("Model") if boat then ownedBoat = boat return boat, hum.SeatPart end end if ownedBoat and ownedBoat.Parent then local seat = boatSeat(ownedBoat) if seat then display("Returning to Dinghy…") approachPosition(seat.Position + Vector3.new(0, 3, 0), 10) if boardBoat(ownedBoat) then return ownedBoat, seat end end end scanDealers(true) local nearestDealer, nearestDist = nil, math.huge for _, dealer in ipairs(dealerList) do local dist = (root.Position - dealer.position).Magnitude if dist < nearestDist then nearestDealer, nearestDist = dealer, dist end end if not nearestDealer then display("Searching for Boat Dealer…") return nil, nil end display("Approaching Boat Dealer…") if (root.Position - nearestDealer.position).Magnitude > BOAT_APPROACH_RANGE then approachPosition(nearestDealer.position, BOAT_APPROACH_RANGE) end display("Purchasing Dinghy…") local boat = buyDinghy() if not boat then return nil, nil end ownedBoat = boat display("Boarding Dinghy…") local seat = boatSeat(boat) if seat then approachPosition(seat.Position + Vector3.new(0, 3, 0), 8) if boardBoat(boat) then return boat, seat end end return nil, nil end -- 3D CONTINUOUS FLIGHT CONTROLLER local persistentLinearVelocity = nil local persistentAttachment = nil local persistentNoclipConn = nil local function getFlightConstraint(boat, seat) local motionPart = seat.AssemblyRootPart or seat if not persistentLinearVelocity or persistentLinearVelocity.Parent ~= motionPart then if persistentLinearVelocity then persistentLinearVelocity:Destroy() end if persistentAttachment then persistentAttachment:Destroy() end persistentAttachment = Instance.new("Attachment") persistentAttachment.Name = "ContinuousFlightAttachment" persistentAttachment.Parent = motionPart persistentLinearVelocity = Instance.new("LinearVelocity") persistentLinearVelocity.Name = "ContinuousFlightVelocity" persistentLinearVelocity.Attachment0 = persistentAttachment persistentLinearVelocity.RelativeTo = Enum.ActuatorRelativeTo.World persistentLinearVelocity.ForceLimitsEnabled = false persistentLinearVelocity.MaxForce = math.huge persistentLinearVelocity.VectorVelocity = Vector3.zero persistentLinearVelocity.Parent = motionPart end if not persistentNoclipConn then persistentNoclipConn = RunService.Stepped:Connect(function() local char = player.Character if char then for _, p in ipairs(char:GetDescendants()) do if p:IsA("BasePart") then p.CanCollide = false end end end if boat and boat.Parent then for _, p in ipairs(boat:GetDescendants()) do if p:IsA("BasePart") then p.CanCollide = false end end end end) end return persistentLinearVelocity, motionPart end -- Moves in a single straight 3D vector directly to the destination local function move3D(boat, seat, destination, recordsToArm) local char, root, hum = parts() if not char or not seat or seat.Occupant ~= hum then return "interrupted" end local lv, motionPart = getFlightConstraint(boat, seat) local began = workspace:GetServerTimeNow() local startPos = root.Position local delta = destination - startPos local totalDist = delta.Magnitude if totalDist <= 4.0 then return "arrived" end local initialDir = delta.Unit local timeout = (totalDist / SPEED_MIN) + 3.0 local outcome = "arrived" while not stopped and boat.Parent and seat.Parent and player.Character == char and hum.Health > 0 do RunService.Heartbeat:Wait() if seat.Occupant ~= hum then seat:Sit(hum) if seat.Occupant ~= hum then outcome = "interrupted"; break end end local now = workspace:GetServerTimeNow() if now - began > timeout then outcome = "timeout"; break end local currentPos = root.Position local currentDelta = destination - currentPos local currentDist = currentDelta.Magnitude -- Arm collection for all chests in the cluster within 50 studs if recordsToArm then for _, rec in ipairs(recordsToArm) do if not rec.pendingAttempt and (rec.position - currentPos).Magnitude <= 50 then beginPending(rec, 0.05) end end end -- Cutoff check: reached radius or passed destination along 3D flight vector local passed = (currentPos - startPos):Dot(initialDir) >= totalDist if currentDist <= 4.0 or passed then outcome = "arrived" break end local activeSpeed = getSinusoidalSpeed() local dir = currentDist > 0.001 and currentDelta.Unit or initialDir -- Pure 3D Velocity Vector lv.VectorVelocity = dir * activeSpeed -- Snap heading horizontally toward target local hDir = Vector3.new(dir.X, 0, dir.Z) if hDir.Magnitude > 0.01 then motionPart.CFrame = CFrame.lookAt(motionPart.Position, motionPart.Position + hDir.Unit, Vector3.yAxis) end motionPart.AssemblyAngularVelocity = Vector3.zero pcall(function() seat.ThrottleFloat = 1 seat.SteerFloat = 0 seat.MaxSpeed = activeSpeed end) end lv.VectorVelocity = Vector3.zero motionPart.AssemblyAngularVelocity = Vector3.zero if outcome == "arrived" then recordLegPerformance(totalDist, workspace:GetServerTimeNow() - began) end return outcome end -- Optimized Perimeter Grazing & Multi-Chest Collection (Direct 3D Line) local function flyThroughTarget(boat, seat, node) local char, root, hum = parts() if not char or not seat or seat.Occupant ~= hum then return "interrupted" end local recordsList = node.records or {node.record} local entryPoint, centerPoint, exitPoint = Planner.sweepPath(node, root.Position, C.SweepMargin) currentTargetBoxCenter = centerPoint -- Step 1: Direct 3D approach straight to closest boundary perimeter display(string.format("Approach 3D · %s", node.isCluster and ("Cluster (" .. #recordsList .. ")") or node.record.name)) currentRouteDestination = entryPoint local approachOutcome = move3D(boat, seat, entryPoint, recordsList) if approachOutcome ~= "arrived" then return approachOutcome end -- Step 2: Direct 3D slice through boundary surface display(string.format("Piercing · %s", node.isCluster and ("Cluster (" .. #recordsList .. ")") or node.record.name)) local activeAttempts = {} for _, rec in ipairs(recordsList) do local att = beginPending(rec, 0.05) table.insert(activeAttempts, att) end currentRouteDestination = exitPoint local sweepOutcome = move3D(boat, seat, exitPoint, recordsList) for _, att in ipairs(activeAttempts) do att.crossed = true end currentRouteDestination = nil currentTargetBoxCenter = nil return sweepOutcome end -- CLUSTER FUSION & SNAPSHOT local function buildFusedClusters(rawNodes) local clusters = {} local merged = {} for i = 1, #rawNodes do if not merged[i] then local nodeA = rawNodes[i] local group = {nodeA} merged[i] = true for j = i + 1, #rawNodes do if not merged[j] then local nodeB = rawNodes[j] local hDist = (Vector2.new(nodeA.position.X, nodeA.position.Z) - Vector2.new(nodeB.position.X, nodeB.position.Z)).Magnitude local vDist = math.abs(nodeA.position.Y - nodeB.position.Y) -- Merge if hitboxes overlap (<= 84 studs horizontal, <= 80 studs vertical) if hDist <= CLUSTER_MERGE_DIST_H and vDist <= CLUSTER_MERGE_DIST_V then merged[j] = true table.insert(group, nodeB) end end end if #group == 1 then table.insert(clusters, nodeA) else local sumPos = Vector3.zero local totalVal, totalLow, totalHigh = 0, 0, 0 local recordsList = {} local minReady = 0 for _, n in ipairs(group) do sumPos += n.position totalVal += n.value totalLow += n.low totalHigh += n.high table.insert(recordsList, n.record) minReady = math.max(minReady, n.readyAt or 0) end local centroid = sumPos / #group table.insert(clusters, { id = nodeA.id, position = centroid, value = totalVal, low = totalLow, high = totalHigh, records = recordsList, record = nodeA.record, confidence = 1, hazard = 0, contest = 0, reliability = 1, readyAt = minReady, cooldown = 0, isCluster = true, clusterCount = #group }) end end end return clusters end local function snapshotNodes(now, includeCooldown, includeUnknown) local rawNodes = {} local silver = chestEconomy.Silver.rewards[REWARD_SEA] local unit = (silver[1] + silver[2]) / 2 for _, r in ipairs(records) do if r.pendingUntil and now < r.pendingUntil then continue end if now < r.cooldown and not includeCooldown then continue end local reward = economyOf(r).rewards[REWARD_SEA] local ready = available(r.part) local predicted = not ready and r.emptyAt and r.readyAt and r.readyAt < math.huge and now <= r.readyAt + C.OverdueGrace local exploration = includeUnknown and not ready and not predicted and r.state == "unknown" if not ready and not predicted and not exploration then continue end table.insert(rawNodes, { id = r.id, record = r, position = r.position, predicted = predicted, exploration = exploration, partCFrame = r.spawnPart and r.spawnPart.CFrame, value = (reward[1] + reward[2]) / (2 * unit), low = reward[1], high = reward[2], confidence = ready and 1 or 0.7, hazard = 0, contest = 0, reliability = 1, readyAt = (ready or exploration) and now or r.readyAt, cooldown = r.cooldown, respawn = respawnOf(r), }) end return buildFusedClusters(rawNodes) end local function plannerOptions() return { speed = C.BoatSpeed, maxTravel = MAX_TRAVEL_SECONDS, travelEstimator = function(from, dest) return Planner.travelSeconds(from, dest, C.BoatSpeed) end, travelFactor = timing.travelFactor, service = timing.service, sweepMargin = C.SweepMargin, maxWait = C.MaxRespawnWait, overdueGrace = C.OverdueGrace, depth = LOOKAHEAD_STOPS, width = C.BeamWidth, branch = C.BranchWidth, smoothing = 5, budget = C.PlanBudgetSeconds } end local function choose(root, forcedRecord) local now = workspace:GetServerTimeNow() local nodes = snapshotNodes(now) local plan = Planner.plan(root.Position, nodes, now, plannerOptions(), forcedRecord and forcedRecord.id) if not plan and not forcedRecord then plan = Planner.plan(root.Position, snapshotNodes(now, false, true), now, plannerOptions()) end if plan then plan.node = plan.first plan.record = plan.first.record end return plan end -- Find next respawning chest or fallback to first collected chest when waiting local function getNextRespawnTarget() local now = workspace:GetServerTimeNow() local earliestRecord = nil local earliestTime = math.huge for _, r in ipairs(records) do if r.readyAt and r.readyAt > 0 and r.readyAt < earliestTime then earliestTime = r.readyAt earliestRecord = r end end return earliestRecord or firstCollectedRecord end -- TRACERS & GOLD 100x100x100 HITBOX VISUALIZER local traceParts = {} local hitboxPart = Instance.new("Part") hitboxPart.Name = "Hitbox100VisualizerPart" hitboxPart.Size = Vector3.new(100, 100, 100) hitboxPart.Transparency = 1 hitboxPart.Anchored = true hitboxPart.CanCollide = false hitboxPart.CanTouch = false hitboxPart.CanQuery = false hitboxPart.Parent = workspace.Terrain local hitboxOutline = Instance.new("SelectionBox") hitboxOutline.Name = "Hitbox100GoldOutline" hitboxOutline.Color3 = Color3.fromRGB(255, 215, 0) -- Gold hitboxOutline.LineThickness = 0.25 hitboxOutline.Adornee = hitboxPart hitboxOutline.Visible = false hitboxOutline.Parent = workspace.Terrain table.insert(traceParts, hitboxPart) table.insert(traceParts, hitboxOutline) if SHOW_ROUTE_TRACERS then local from = Instance.new("Attachment", workspace.Terrain) local dest = Instance.new("Attachment", workspace.Terrain) local beam = Instance.new("Beam", workspace.Terrain) beam.Name = "FarmRouteCurrent" beam.Attachment0 = from beam.Attachment1 = dest beam.FaceCamera = true beam.Segments = 1 beam.Width0, beam.Width1 = 0.35, 0.35 beam.Color = ColorSequence.new(Color3.fromRGB(75, 215, 255)) beam.Transparency = NumberSequence.new(0.2) beam.Enabled = false table.insert(traceParts, beam) table.insert(traceParts, from) table.insert(traceParts, dest) table.insert(connections, RunService.RenderStepped:Connect(function() local _, root = parts() if stopped or not root or not currentRouteDestination then beam.Enabled = false hitboxOutline.Visible = false return end from.WorldPosition = root.Position dest.WorldPosition = currentRouteDestination beam.Enabled = true if currentTargetBoxCenter then hitboxPart.CFrame = CFrame.new(currentTargetBoxCenter) hitboxOutline.Visible = true else hitboxOutline.Visible = false end end)) end -- MAIN FARM LOOP task.spawn(function() local ok, err = xpcall(function() while not stopped do currentTarget = nil scanDealers() refreshChests() local _, root = waitCharacter(C.CharacterTimeout) if stopped then break end if not root then task.wait(0.5); continue end local boat, seat = ensureSeatedInBoat() if not boat or not seat then task.wait(0.5) continue end local plan = choose(root) if not plan then local nextTarget = getNextRespawnTarget() if nextTarget then local fakeNode = {position = nextTarget.position, record = nextTarget} local entryPoint, centerPoint = Planner.sweepPath(fakeNode, root.Position, C.SweepMargin) currentTargetBoxCenter = centerPoint currentRouteDestination = entryPoint local remaining = math.max(0, (nextTarget.readyAt or 0) - workspace:GetServerTimeNow()) display(string.format("Intercepting · %s (%.0fs)", nextTarget.name, remaining)) move3D(boat, seat, entryPoint, {nextTarget}) else display("Waiting for chest respawns…") end task.wait(0.5) continue end local node = plan.node currentTarget = node.record display(string.format("Route · %s", node.isCluster and ("Cluster (" .. node.clusterCount .. ")") or node.record.name)) -- Execute direct 3D flight straight to the target boundary and through local outcome = flyThroughTarget(boat, seat, node) if outcome ~= "arrived" then if node.records then for _, rec in ipairs(node.records) do rec.failures = (rec.failures or 0) + 1 rec.cooldown = workspace:GetServerTimeNow() + 10 end else node.record.failures = (node.record.failures or 0) + 1 node.record.cooldown = workspace:GetServerTimeNow() + 10 end end end end, debug.traceback) stopped = true if persistentNoclipConn then persistentNoclipConn:Disconnect() end if persistentLinearVelocity then persistentLinearVelocity:Destroy() end if persistentAttachment then persistentAttachment:Destroy() end for _, conn in ipairs(connections) do conn:Disconnect() end for _, part in ipairs(traceParts) do part:Destroy() end if gui.Parent then gui:Destroy() end if globalEnvironment.ChestFarmerBoatStop == stop then globalEnvironment.ChestFarmerBoatStop = nil end if not ok then warn(err) end end)