
Key Required
script
Lua Script•504 lines (13972 chars)
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")
local UserInputService = game:GetService("UserInputService")
local Workspace = game:GetService("Workspace")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local LocalPlayer = Players.LocalPlayer
-- Game references
local Remotes = ReplicatedStorage:WaitForChild("Remotes")
local CollectEvent = Remotes:WaitForChild("CollectEvent")
local PlaceEvent = Remotes:WaitForChild("PlaceEvent")
local DropEvent = Remotes:WaitForChild("DropEvent")
local PlayPlaceAnimation = ReplicatedStorage:WaitForChild("PlayPlaceAnimation")
local Dinosaurs = Workspace:WaitForChild("Dinosaurs")
local Collectables = Workspace:WaitForChild("Collectables")
local Config = ReplicatedStorage:WaitForChild("Config")
local Upgrades = require(Config:WaitForChild("Upgrades"))
local ClientData = require(ReplicatedStorage:WaitForChild("Modules"):WaitForChild("ClientData"))
-- Load Fluent UI Library
local Fluent = loadstring(game:HttpGet("https://github.com/dawid-scripts/Fluent/releases/latest/download/main.lua"))()
-- STATE shim: use live-reload's STATE if present, otherwise fall back to a
-- lightweight local implementation so the script also runs when pasted directly.
local STATE = STATE or (function()
local connections = {}
local cleanups = {}
local alive = true
local bound
local s = {}
function s.alive()
return alive
end
function s.connect(signal, fn)
local c = signal:Connect(fn)
table.insert(connections, c)
return c
end
function s.onCleanup(fn)
table.insert(cleanups, fn)
if not bound then
bound = true
pcall(function()
game:BindToClose(function()
for _, f in ipairs(cleanups) do pcall(f) end
alive = false
end)
end)
end
end
return s
end)()
-- State settings
local settings = {
Highlight = true,
AutoFarm = false,
PickupLimit = 4,
WalkSpeed = 16,
JumpPower = 50,
Fly = false,
FlySpeed = 50,
Noclip = false,
}
local currentPart = nil
local currentBox = nil
local currentOrigT = nil
local farmThread = nil
local function clearSlot()
if currentPart then
currentPart.Transparency = currentOrigT
currentOrigT = nil
currentPart = nil
end
if currentBox then
currentBox:Destroy()
currentBox = nil
end
end
local function applySlot(part)
if currentPart == part then return end
clearSlot()
currentOrigT = part.Transparency
currentPart = part
part.Transparency = 0
local box = Instance.new("SelectionBox")
box.Adornee = part
box.Color3 = Color3.fromRGB(0, 255, 120)
box.SurfaceColor3 = Color3.fromRGB(0, 255, 120)
box.SurfaceTransparency = 0.7
box.LineThickness = 0.03
box.Parent = Workspace
currentBox = box
end
local lastDino, lastPart
local function getRoot()
local char = LocalPlayer.Character
return char and char:FindFirstChild("HumanoidRootPart")
end
local function getHumanoid()
local char = LocalPlayer.Character
return char and char:FindFirstChildOfClass("Humanoid")
end
local function getAllHeldBones()
local out = {}
local char = LocalPlayer.Character
local bp = LocalPlayer.Backpack
if char then
local tool = char:FindFirstChildOfClass("Tool")
if tool and tool:GetAttribute("Part") ~= nil then
table.insert(out, tool)
end
end
if bp then
for _, v in ipairs(bp:GetChildren()) do
if v:IsA("Tool") and v:GetAttribute("Part") ~= nil then
table.insert(out, v)
end
end
end
return out
end
local function getEquippedBoneTool()
local char = LocalPlayer.Character
if not char then return nil end
local tool = char:FindFirstChildOfClass("Tool")
if not tool then return nil end
if tool:GetAttribute("Part") == nil then return nil end
return tool
end
local function carryCapacity()
local ok, data = pcall(function()
return ClientData.Get()
end)
if not ok or not data or not data.Upgrades then
return 4
end
local lvl = data.Upgrades.Carry or 0
local cfg = Upgrades.Carry[lvl]
return (cfg and cfg.Value) or 2
end
local function findSlot(dinoName, partName)
local dino = Dinosaurs:FindFirstChild(dinoName)
if not dino then return nil end
for _, desc in ipairs(dino:GetDescendants()) do
if desc:IsA("BasePart")
and tostring(desc.Name) == tostring(partName)
and not desc:GetAttribute("Placed")
then
return desc
end
end
return nil
end
local function nearestCollectable()
local root = getRoot()
local best, bestDist
for _, v in ipairs(Collectables:GetChildren()) do
if v:IsA("BasePart") and v.Parent then
local d = root and (root.Position - v.Position).Magnitude or 9e9
if not best or d < bestDist then
best, bestDist = v, d
end
end
end
return best, bestDist
end
local function goto(pos)
local root = getRoot()
if not root then return false end
root.CFrame = CFrame.new(pos + Vector3.new(0, 2, 0))
task.wait(0.05)
return true
end
local function attemptCollect(target)
pcall(function()
CollectEvent:FireServer(target)
PlayPlaceAnimation:Fire()
end)
end
local function attemptPlace(slot)
pcall(function()
PlaceEvent:FireServer(slot)
PlayPlaceAnimation:Fire()
end)
end
local function attemptDrop(tool)
pcall(function()
DropEvent:FireServer(tool)
end)
end
local function collectPhase()
local limit = settings.PickupLimit
local root = getRoot()
if not root then return false end
for _ = 1, limit do
if not settings.AutoFarm then return false end
local held = #getAllHeldBones()
if held >= limit then break end
local target = nearestCollectable()
if not target then break end
goto(target.Position)
attemptCollect(target)
task.wait(0.18)
end
return true
end
local function placePhase()
local tries = 0
while settings.AutoFarm and tries < 40 do
tries = tries + 1
local tool = getEquippedBoneTool()
if not tool then break end
local dinoName = tool:GetAttribute("Dinosaur")
local partName = tostring(tool:GetAttribute("Part"))
local slot = findSlot(dinoName, partName)
if not slot then
attemptDrop(tool)
task.wait(0.15)
continue
end
if settings.Highlight then applySlot(slot) end
goto(slot.Position)
attemptPlace(slot)
task.wait(0.25)
if slot:GetAttribute("Placed") == nil and getEquippedBoneTool() == tool then
attemptDrop(tool)
task.wait(0.15)
end
end
clearSlot()
end
local function farmLoop()
while STATE.alive() and settings.AutoFarm do
local ok = pcall(function()
collectPhase()
placePhase()
end)
if not ok then
task.wait(0.5)
end
end
clearSlot()
end
local function stopFarm()
if farmThread then
task.cancel(farmThread)
farmThread = nil
end
end
local function startFarm()
stopFarm()
farmThread = task.spawn(farmLoop)
end
settings.PickupLimit = carryCapacity()
-- ============================================================
-- FLUENT WINDOW & TABS SETUP
-- ============================================================
local Window = Fluent:CreateWindow({
Title = "Dino Bone Hub",
SubTitle = "Fast Farm & Tools",
TabWidth = 150,
Size = UDim2.fromOffset(540, 380),
Acrylic = true,
Theme = "Dark",
MinimizeKey = Enum.KeyCode.RightShift
})
local Tabs = {
Main = Window:AddTab({ Title = "Farm", Icon = "bone" }),
Player = Window:AddTab({ Title = "Local Player", Icon = "user" })
}
local Options = Fluent.Options
-- Farm Tab Controls
local HighlightToggle = Tabs.Main:AddToggle("HighlightToggle", {
Title = "Slot Highlight",
Description = "Highlights placement slot for held bone",
Default = true
})
HighlightToggle:OnChanged(function()
settings.Highlight = Options.HighlightToggle.Value
if not settings.Highlight then clearSlot() end
end)
local FarmToggle = Tabs.Main:AddToggle("FarmToggle", {
Title = "Auto Farm (Fast)",
Description = "Batch collects bones & places in skeletons",
Default = false
})
FarmToggle:OnChanged(function()
settings.AutoFarm = Options.FarmToggle.Value
if settings.AutoFarm then
startFarm()
else
stopFarm()
clearSlot()
end
end)
local LimitSlider = Tabs.Main:AddSlider("LimitSlider", {
Title = "Pickup Limit",
Description = "Auto-detected from Carry upgrade level",
Default = math.clamp(carryCapacity(), 1, 50),
Min = 1,
Max = 50,
Rounding = 0,
Callback = function(Value)
settings.PickupLimit = math.floor(Value)
end
})
-- Auto-detect pickup limit (carry capacity) and sync the slider
local lastDetected = -1
task.spawn(function()
while STATE.alive() do
task.wait(2)
local ok, cap = pcall(carryCapacity)
if ok and cap ~= lastDetected then
lastDetected = cap
settings.PickupLimit = cap
pcall(function()
Options.LimitSlider:Set(cap)
end)
end
end
end)
-- Player Tab Controls
local FlyToggle = Tabs.Player:AddToggle("FlyToggle", {
Title = "Fly",
Description = "WASD + Space/LeftShift to fly",
Default = false
})
FlyToggle:OnChanged(function()
settings.Fly = Options.FlyToggle.Value
end)
local FlySpeedSlider = Tabs.Player:AddSlider("FlySpeedSlider", {
Title = "Fly Speed",
Description = "Flight movement speed",
Default = 50,
Min = 5,
Max = 300,
Rounding = 0,
Callback = function(Value)
settings.FlySpeed = math.floor(Value)
end
})
local NoclipToggle = Tabs.Player:AddToggle("NoclipToggle", {
Title = "Noclip",
Description = "Walk through walls",
Default = false
})
NoclipToggle:OnChanged(function()
settings.Noclip = Options.NoclipToggle.Value
end)
local SpeedSlider = Tabs.Player:AddSlider("SpeedSlider", {
Title = "WalkSpeed",
Description = "Player movement speed",
Default = 16,
Min = 16,
Max = 200,
Rounding = 0,
Callback = function(Value)
settings.WalkSpeed = math.floor(Value)
local hum = getHumanoid()
if hum then hum.WalkSpeed = settings.WalkSpeed end
end
})
local JumpSlider = Tabs.Player:AddSlider("JumpSlider", {
Title = "JumpPower",
Description = "Player jump height",
Default = 50,
Min = 50,
Max = 300,
Rounding = 0,
Callback = function(Value)
settings.JumpPower = math.floor(Value)
local hum = getHumanoid()
if hum then hum.UseJumpPower = true hum.JumpPower = settings.JumpPower end
end
})
Window:SelectTab(1)
-- ============================================================
-- SYSTEM CONNECTIONS
-- ============================================================
-- RenderStepped for Fly, Noclip, WalkSpeed, JumpPower
STATE.connect(RunService.RenderStepped, function(delta)
local hum = getHumanoid()
local root = getRoot()
if hum then
if hum.WalkSpeed ~= settings.WalkSpeed then
hum.WalkSpeed = settings.WalkSpeed
end
if settings.JumpPower > 50 then
hum.UseJumpPower = true
hum.JumpPower = settings.JumpPower
end
end
-- Fly logic
if settings.Fly and root then
root.Velocity = Vector3.zero
local cam = Workspace.CurrentCamera
local moveDir = Vector3.zero
if UserInputService:IsKeyDown(Enum.KeyCode.W) then moveDir = moveDir + cam.CFrame.LookVector end
if UserInputService:IsKeyDown(Enum.KeyCode.S) then moveDir = moveDir - cam.CFrame.LookVector end
if UserInputService:IsKeyDown(Enum.KeyCode.A) then moveDir = moveDir - cam.CFrame.RightVector end
if UserInputService:IsKeyDown(Enum.KeyCode.D) then moveDir = moveDir + cam.CFrame.RightVector end
if UserInputService:IsKeyDown(Enum.KeyCode.Space) then moveDir = moveDir + Vector3.new(0, 1, 0) end
if UserInputService:IsKeyDown(Enum.KeyCode.LeftShift) then moveDir = moveDir - Vector3.new(0, 1, 0) end
if moveDir.Magnitude > 0 then
moveDir = moveDir.Unit
root.CFrame = root.CFrame + moveDir * settings.FlySpeed * delta
end
end
end)
-- Stepped for Noclip
STATE.connect(RunService.Stepped, function()
if settings.Noclip and LocalPlayer.Character then
for _, part in ipairs(LocalPlayer.Character:GetDescendants()) do
if part:IsA("BasePart") and part.CanCollide then
part.CanCollide = false
end
end
end
end)
-- Heartbeat Highlight Update
STATE.connect(RunService.Heartbeat, function()
if not settings.Highlight then return end
local tool = getEquippedBoneTool()
if not tool then
if lastDino ~= nil then
clearSlot()
lastDino = nil
lastPart = nil
end
return
end
local dinoName = tool:GetAttribute("Dinosaur")
local partName = tostring(tool:GetAttribute("Part"))
if dinoName == lastDino and partName == lastPart then return end
lastDino = dinoName
lastPart = partName
clearSlot()
local slot = findSlot(dinoName, partName)
if slot then applySlot(slot) end
end)
STATE.onCleanup(function()
stopFarm()
clearSlot()
pcall(function() Fluent:Destroy() end)
end)Features & Information
Made by AI.
Opensource.
Farm
Slot Highlight - Highlights placement slot for held bone
Auto Farm - Batch collect bones and place in skeletons
Pick up limit - you can ignore this, auto detects from carry upgrade level.
Local Player
Fly
Fly speed
Noclip
Walkspeed
Jump power
Unlock third person.
Community Comments (0)
No comments yet for this script.
