BobloScript.com

Description

This Clean The Library script is made for players who want a calmer and more automatic way to organize books during long library cleaning runs. Since the game is built around picking up scattered books, finding the correct shelves, sorting them into the right sections, and cleaning the library as efficiently as possible, this script focuses on helping players reduce repetitive book placement and keep progress moving steadily. The Auto Clean Library feature is useful when players want to organize books without manually checking every shelf, carrying books back and forth, and repeating the same sorting process for a long time. It can help during solo runs, slower cleanup sessions, or when the library becomes crowded with many unsorted books. Because this version works at slow speed, it is better suited for stable and controlled cleaning rather than aggressive fast farming. This can be useful for players who want the automation to look smoother, avoid rushed movement, and let the script handle book organization more carefully while the library is being cleaned. The script is especially helpful for players who want to focus on overall progress, leaderboard attempts, completion goals, or simply make the cleaning process less tiring. Instead of spending the whole session manually sorting book after book, Auto Clean Library helps keep the library cleanup loop more consistent. Overall, this Clean The Library script is useful for players who want automatic book organization, slower and more stable library cleaning, easier solo progress, and less repetitive manual sorting during long cleanup runs.

Functions

  • Auto Clean Library (Slow speed)

Script Code

Raw Code
-- Simple Book Organizer with Toggle + Ctrl+LMB Mouse Togglelocal Players = game:GetService("Players")local ReplicatedStorage = game:GetService("ReplicatedStorage")local Workspace = game:GetService("Workspace")local CollectionService = game:GetService("CollectionService")local UserInputService = game:GetService("UserInputService")local Settings = {    Enabled = false,    FastMode = false,    MouseLocked = false,}local function isCtrlDown()    return UserInputService:IsKeyDown(Enum.KeyCode.LeftControl)        or UserInputService:IsKeyDown(Enum.KeyCode.RightControl)endlocal function setMouseLocked(locked)    Settings.MouseLocked = locked    pcall(function()        if locked then            UserInputService.MouseBehavior = Enum.MouseBehavior.LockCenter            UserInputService.MouseIconEnabled = false        else            UserInputService.MouseBehavior = Enum.MouseBehavior.Default            UserInputService.MouseIconEnabled = true        end    end)endlocal function safeCancel(thread)    if thread then        pcall(task.cancel, thread)    endendlocal function CreateUI()    local screenGui = Instance.new("ScreenGui")    screenGui.Name = "BookOrganizerGUI"    screenGui.ResetOnSpawn = false    screenGui.Parent = Players.LocalPlayer:WaitForChild("PlayerGui")    local mainFrame = Instance.new("Frame")    mainFrame.Size = UDim2.new(0, 300, 0, 150)    mainFrame.Position = UDim2.new(0.5, -150, 0.5, -75)    mainFrame.BackgroundColor3 = Color3.fromRGB(25, 25, 35)    mainFrame.BackgroundTransparency = 0.05    mainFrame.BorderSizePixel = 0    mainFrame.ClipsDescendants = true    mainFrame.Parent = screenGui    local titleBar = Instance.new("Frame")    titleBar.Size = UDim2.new(1, 0, 0, 35)    titleBar.BackgroundColor3 = Color3.fromRGB(50, 50, 70)    titleBar.BackgroundTransparency = 0.3    titleBar.BorderSizePixel = 0    titleBar.Parent = mainFrame    local title = Instance.new("TextLabel")    title.Size = UDim2.new(1, -35, 1, 0)    title.BackgroundTransparency = 1    title.Text = "πŸ“š Book Organizer"    title.TextColor3 = Color3.fromRGB(255, 255, 255)    title.TextSize = 16    title.Font = Enum.Font.GothamBold    title.Parent = titleBar    local closeBtn = Instance.new("TextButton")    closeBtn.Size = UDim2.new(0, 25, 0, 25)    closeBtn.Position = UDim2.new(1, -30, 0, 5)    closeBtn.BackgroundColor3 = Color3.fromRGB(200, 50, 50)    closeBtn.BackgroundTransparency = 0.5    closeBtn.Text = "βœ•"    closeBtn.TextColor3 = Color3.fromRGB(255, 255, 255)    closeBtn.TextSize = 14    closeBtn.Font = Enum.Font.GothamBold    closeBtn.BorderSizePixel = 0    closeBtn.Parent = titleBar    local statusLabel = Instance.new("TextLabel")    statusLabel.Size = UDim2.new(1, -20, 0, 25)    statusLabel.Position = UDim2.new(0, 10, 0, 45)    statusLabel.BackgroundTransparency = 1    statusLabel.Text = "πŸ”΄ Disabled"    statusLabel.TextColor3 = Color3.fromRGB(255, 100, 100)    statusLabel.TextSize = 14    statusLabel.Font = Enum.Font.Gotham    statusLabel.TextXAlignment = Enum.TextXAlignment.Left    statusLabel.Parent = mainFrame    local mouseStatusLabel = Instance.new("TextLabel")    mouseStatusLabel.Size = UDim2.new(1, -20, 0, 22)    mouseStatusLabel.Position = UDim2.new(0, 10, 0, 72)    mouseStatusLabel.BackgroundTransparency = 1    mouseStatusLabel.Text = "πŸ–±οΈ Mouse: Free"    mouseStatusLabel.TextColor3 = Color3.fromRGB(180, 180, 200)    mouseStatusLabel.TextSize = 13    mouseStatusLabel.Font = Enum.Font.Gotham    mouseStatusLabel.TextXAlignment = Enum.TextXAlignment.Left    mouseStatusLabel.Parent = mainFrame    local mouseHintLabel = Instance.new("TextLabel")    mouseHintLabel.Size = UDim2.new(1, -20, 0, 18)    mouseHintLabel.Position = UDim2.new(0, 10, 0, 94)    mouseHintLabel.BackgroundTransparency = 1    mouseHintLabel.Text = "Ctrl + LMB β€” toggle mouse"    mouseHintLabel.TextColor3 = Color3.fromRGB(130, 130, 150)    mouseHintLabel.TextSize = 11    mouseHintLabel.Font = Enum.Font.Gotham    mouseHintLabel.TextXAlignment = Enum.TextXAlignment.Left    mouseHintLabel.Parent = mainFrame    local toggleBtn = Instance.new("TextButton")    toggleBtn.Size = UDim2.new(0, 80, 0, 35)    toggleBtn.Position = UDim2.new(1, -90, 0, 100)    toggleBtn.BackgroundColor3 = Color3.fromRGB(200, 60, 60)    toggleBtn.BackgroundTransparency = 0.2    toggleBtn.Text = "START"    toggleBtn.TextColor3 = Color3.fromRGB(255, 255, 255)    toggleBtn.TextSize = 14    toggleBtn.Font = Enum.Font.GothamBold    toggleBtn.BorderSizePixel = 0    toggleBtn.Parent = mainFrame    local dragging = false    local dragStart, startPos    titleBar.InputBegan:Connect(function(input)        if input.UserInputType == Enum.UserInputType.MouseButton1 and not isCtrlDown() then            dragging = true            dragStart = input.Position            startPos = mainFrame.Position        end    end)    titleBar.InputEnded:Connect(function(input)        if input.UserInputType == Enum.UserInputType.MouseButton1 then            dragging = false        end    end)    UserInputService.InputChanged:Connect(function(input)        if dragging and input.UserInputType == Enum.UserInputType.MouseMovement then            local delta = input.Position - dragStart            mainFrame.Position = UDim2.new(                startPos.X.Scale, startPos.X.Offset + delta.X,                startPos.Y.Scale, startPos.Y.Offset + delta.Y            )        end    end)    closeBtn.MouseButton1Click:Connect(function()        Settings.Enabled = false        setMouseLocked(false)        screenGui:Destroy()    end)    return screenGui, toggleBtn, statusLabel, mouseStatusLabel, mouseHintLabelendlocal gui, toggleBtn, statusLabel, mouseStatusLabel, mouseHintLabel = CreateUI()local isRunning = falselocal currentCoroutine = nillocal function updateMouseUI(ctrlActive)    if Settings.MouseLocked then        mouseStatusLabel.Text = "πŸ–±οΈ Mouse: Locked"        mouseStatusLabel.TextColor3 = Color3.fromRGB(100, 200, 255)    else        mouseStatusLabel.Text = "πŸ–±οΈ Mouse: Free"        mouseStatusLabel.TextColor3 = Color3.fromRGB(180, 180, 200)    end    if ctrlActive then        mouseHintLabel.Text = "Ctrl + LMB β€” toggle mouse (Ctrl held)"        mouseHintLabel.TextColor3 = Color3.fromRGB(255, 220, 100)    else        mouseHintLabel.Text = "Ctrl + LMB β€” toggle mouse"        mouseHintLabel.TextColor3 = Color3.fromRGB(130, 130, 150)    endendlocal function toggleMouse()    setMouseLocked(not Settings.MouseLocked)    updateMouseUI(isCtrlDown())endUserInputService.InputBegan:Connect(function(input, gameProcessed)    if input.UserInputType == Enum.UserInputType.MouseButton1 and isCtrlDown() then        toggleMouse()        return    end    if input.KeyCode == Enum.KeyCode.LeftControl or input.KeyCode == Enum.KeyCode.RightControl then        updateMouseUI(true)    endend)UserInputService.InputEnded:Connect(function(input)    if input.KeyCode == Enum.KeyCode.LeftControl or input.KeyCode == Enum.KeyCode.RightControl then        updateMouseUI(false)    endend)updateMouseUI(false)local Loader = require(ReplicatedStorage.Packages.Loader)local ReplicaController = require(Loader.Shared.Utility.ReplicaController)local BooksData = require(Loader.Shared.Data.Books)local LibraryReplica = nilfor _, r in pairs(ReplicaController._replicas) do    if r.Class == "Library" then        LibraryReplica = r        break    endendif not LibraryReplica then    ReplicaController.ReplicaOfClassCreated("Library", function(replica)        LibraryReplica = replica    end)    while not LibraryReplica do        task.wait()    endendlocal Library = Workspace.Librarylocal BooksFolder = Library.Bookslocal player = Players.LocalPlayerplayer.CameraMode = Enum.CameraMode.Classicplayer.CameraMinZoomDistance = 20task.spawn(function()    task.wait(0.1)    player.CameraMinZoomDistance = 0.5end)local shelfModels = {}for _, shelfModel in ipairs(CollectionService:GetTagged("Shelf")) do    shelfModels[shelfModel.Name] = shelfModelendlocal function getShelfAssignedSeries(shelfId)    local shelfData = LibraryReplica.Data.Shelves[shelfId]    if not shelfData then return nil end    for _, placedBook in pairs(shelfData.Books) do        local bookName = typeof(placedBook) == "Instance" and placedBook.Name or placedBook        local seriesName = bookName:match("^(.-)_(.+)$")        if seriesName then return seriesName end    endendlocal function findShelfForSeries(seriesName, genreName, volumeCount)    for shelfId, shelfData in pairs(LibraryReplica.Data.Shelves) do        if not shelfData.Completed and shelfData.Category == genreName then            local shelfModel = shelfModels[shelfId]            if shelfModel and shelfModel:GetAttribute("Width") == volumeCount then                if getShelfAssignedSeries(shelfId) == seriesName then                    return shelfModel                end            end        end    end    for shelfId, shelfData in pairs(LibraryReplica.Data.Shelves) do        if not shelfData.Completed and shelfData.Category == genreName then            local shelfModel = shelfModels[shelfId]            if shelfModel and shelfModel:GetAttribute("Width") == volumeCount then                if not getShelfAssignedSeries(shelfId) and next(shelfData.Books) == nil then                    return shelfModel                end            end        end    endendlocal function teleportTo(obj)    local char = player.Character    local root = char and char:FindFirstChild("HumanoidRootPart")    local part = obj:IsA("Model") and (obj.PrimaryPart or obj:FindFirstChildOfClass("BasePart")) or obj    if root and part then        root.CFrame = CFrame.new(part.Position + Vector3.new(0, 2, 0))        task.wait(0.05)    endendlocal function organizeBooks()    for _, book in ipairs(BooksFolder:GetChildren()) do        if not isRunning then break end        task.wait(0.02)        local seriesName, volumeStr = book.Name:match("^(.-)_(.+)$")        local volumeNum = tonumber(volumeStr)        if seriesName and volumeNum then            local genreName, bookInfo = BooksData.GetCategory(seriesName)            if genreName and bookInfo then                local shelfModel = findShelfForSeries(seriesName, genreName, bookInfo.VolumeCount)                if shelfModel then                    local shelfData = LibraryReplica.Data.Shelves[shelfModel.Name]                    if not (shelfData and shelfData.Books[tostring(volumeNum)]) then                        teleportTo(book)                        LibraryReplica:FireServer("Grab", book)                        task.wait(0.1)                        teleportTo(shelfModel)                        LibraryReplica:FireServer("Place", shelfModel, volumeNum - 1)                        task.wait(0.4)                    end                end            end        end    endendlocal function toggleScript()    isRunning = not isRunning    if isRunning then        toggleBtn.Text = "STOP"        toggleBtn.BackgroundColor3 = Color3.fromRGB(60, 200, 60)        statusLabel.Text = "🟒 Running..."        statusLabel.TextColor3 = Color3.fromRGB(100, 255, 100)        Settings.Enabled = true        safeCancel(currentCoroutine)        currentCoroutine = task.spawn(function()            while isRunning do                local success, err = pcall(organizeBooks)                if not success then                    warn("Book Organizer error:", err)                    statusLabel.Text = "❌ Error"                    statusLabel.TextColor3 = Color3.fromRGB(255, 100, 100)                    task.wait(2)                end                task.wait(5)            end        end)    else        toggleBtn.Text = "START"        toggleBtn.BackgroundColor3 = Color3.fromRGB(200, 60, 60)        statusLabel.Text = "πŸ”΄ Disabled"        statusLabel.TextColor3 = Color3.fromRGB(255, 100, 100)        Settings.Enabled = false        safeCancel(currentCoroutine)        currentCoroutine = nil    endendtoggleBtn.MouseButton1Click:Connect(toggleScript)Players.LocalPlayer:WaitForChild("PlayerGui").ChildRemoved:Connect(function(child)    if child.Name == "BookOrganizerGUI" then        isRunning = false        setMouseLocked(false)        safeCancel(currentCoroutine)        currentCoroutine = nil    endend)print("βœ… Book Organizer loaded! Ctrl+LMB toggles mouse. Click START to begin.")
Latest changeScript publishedJul 4

Comments

Loading comments…