Piggy intercity script
Key Required

Piggy intercity script

Piggy: Intercity [TREETOPS + DAILY QUESTS]Syafiqah_123456Syafiqah_123456 3.1K views 5.9K executesUpdated Jun 27, 2026
Unrated
00
Lua Script•1458 lines (44103 chars)
--[[
OOF_Dev's Piggy Intercity Script
Tabs:
- Main: reach, resize, speed, jump, noclip, infinite jump
- Visuals: Enemies ESP + Lootcrates ESP + Materials ESP
- Minigames: manual Golf TP + AutoGolf + Bowling
]]

-- // SERVICES
local Players = game:GetService("Players")
local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local Workspace = game:GetService("Workspace")
local TweenService = game:GetService("TweenService")

local LocalPlayer = Players.LocalPlayer

-- // USER DEFAULTS
local DEFAULT_UPDATE_DELAY = 0.0001
local DEFAULT_OFFSET_Z = -1.5
local DEFAULT_HITBOX_SCALE = 3
local DEFAULT_SPEED = 30
local DEFAULT_JUMP = 75

local UPDATE_DELAY = DEFAULT_UPDATE_DELAY
local OFFSET = CFrame.new(0, 0, DEFAULT_OFFSET_Z)
local HITBOX_SCALE = DEFAULT_HITBOX_SCALE
local SPEED_VALUE = DEFAULT_SPEED
local JUMP_VALUE = DEFAULT_JUMP

-- dead NPCs get sent here
local OBLIVION_CFRAME = CFrame.new(0, -1e6, 0)

-- // SETTINGS
local NPC_FOLDER_NAME = "NPCs"
local VALID_NPC_NAMES = {
    ["Infected"] = true,
    ["TankInfected"] = true,
    ["FastInfected"] = true,
    ["PoisonInfected"] = true,
    ["Bandit"] = true,
    ["Morris_Infected"] = true,
    ["Student_Infected1"] = true,
    ["Student_Infected2"] = true,
    ["Student_Infected3"] = true,
    ["Shadewood_Bandit1"] = true,
    ["Shadewood_Bandit2"] = true,
    ["Shadewood_Bandit3"] = true,
    ["Shadewood_Bandit_Blair_Shop"] = true,
    ["Shadewood_Bandit_Cutter"] = true,
    ["Shadewood_Kalen"] = true,
    ["Shadewood_MayorBailey"] = true,
    ["Shadewood_Receptionist"] = true,
    ["Shadewood_Tilly_Shop"] = true,
    ["Shadewood_Tucker"] = true,
}

-- // GOLF CONFIG
local MINIGAME_PATH = Workspace:WaitForChild("Locations")
    :WaitForChild("Gold Golf")
    :WaitForChild("Minigame")
local LANES_FOLDER = MINIGAME_PATH:WaitForChild("Lanes")

-- ========= GUI SETUP =========

local parentGui
if gethui then
    parentGui = gethui()
else
    parentGui = LocalPlayer:WaitForChild("PlayerGui")
end

local screenGui = Instance.new("ScreenGui")
screenGui.Name = "InfectedControlGui"
screenGui.ResetOnSpawn = false
screenGui.Parent = parentGui

local function applyRoundedCorners(instance)
    local uiCorner = Instance.new("UICorner")
    uiCorner.CornerRadius = UDim.new(0.05, 0)
    uiCorner.Parent = instance
end

local TWEEN_TIME = 0.2

-- toggle switch factory
local function createToggleSwitch(parent, name, labelText, pos)
    local label = Instance.new("TextLabel")
    label.Name = name
    label.Size = UDim2.new(0.48, -5, 0, 25)
    label.Position = pos
    label.BackgroundColor3 = Color3.fromRGB(40, 40, 40)
    label.BorderSizePixel = 0
    label.Font = Enum.Font.SourceSansBold
    label.TextSize = 14
    label.TextColor3 = Color3.new(1, 1, 1)
    label.TextXAlignment = Enum.TextXAlignment.Left
    label.Text = labelText .. ": OFF"
    label.Active = true
    label.Parent = parent

    local labelCorner = Instance.new("UICorner")
    labelCorner.CornerRadius = UDim.new(0.05, 0)
    labelCorner.Parent = label

    local slider = Instance.new("Frame")
    slider.Name = "Slider"
    slider.AnchorPoint = Vector2.new(1, 0.5)
    slider.Size = UDim2.new(0, 40, 0, 18)
    slider.Position = UDim2.new(1, -5, 0.5, 0)
    slider.BackgroundColor3 = Color3.fromRGB(60, 60, 60)
    slider.BorderSizePixel = 0
    slider.Parent = label

    local sliderCorner = Instance.new("UICorner")
    sliderCorner.CornerRadius = UDim.new(1, 0)
    sliderCorner.Parent = slider

    local knob = Instance.new("Frame")
    knob.Name = "Knob"
    knob.Size = UDim2.new(0.5, -4, 1, -4)
    knob.Position = UDim2.new(0, 2, 0, 2)
    knob.BackgroundColor3 = Color3.fromRGB(180, 180, 180)
    knob.BorderSizePixel = 0
    knob.Parent = slider

    local knobCorner = Instance.new("UICorner")
    knobCorner.CornerRadius = UDim.new(1, 0)
    knobCorner.Parent = knob

    local clickArea = Instance.new("TextButton")
    clickArea.Name = "ClickArea"
    clickArea.BackgroundTransparency = 1
    clickArea.BorderSizePixel = 0
    clickArea.Size = UDim2.new(1, 0, 1, 0)
    clickArea.Position = UDim2.new(0, 0, 0, 0)
    clickArea.Text = ""
    clickArea.Parent = label

    local state = false
    local onToggleCallback

    local function setState(newState)
        state = newState
        label.Text = labelText .. (state and ": ON" or ": OFF")

        local targetSliderColor = state and Color3.fromRGB(0, 170, 0) or Color3.fromRGB(60, 60, 60)
        TweenService:Create(
            slider,
            TweenInfo.new(TWEEN_TIME, Enum.EasingStyle.Quad, Enum.EasingDirection.Out),
            {BackgroundColor3 = targetSliderColor}
        ):Play()

        local targetPos = state and UDim2.new(0.5, 2, 0, 2) or UDim2.new(0, 2, 0, 2)
        TweenService:Create(
            knob,
            TweenInfo.new(TWEEN_TIME, Enum.EasingStyle.Quad, Enum.EasingDirection.Out),
            {Position = targetPos}
        ):Play()

        if onToggleCallback then
            onToggleCallback(state)
        end
    end

    clickArea.MouseButton1Click:Connect(function()
        setState(not state)
    end)

    return {
        Label = label,
        Slider = slider,
        Knob = knob,
        Get = function() return state end,
        Set = setState,
        OnToggle = function(fn) onToggleCallback = fn end,
    }
end

-- Draggable image toggle button
local toggleButton = Instance.new("ImageButton")
toggleButton.Name = "ToggleButton"
toggleButton.Size = UDim2.new(0, 40, 0, 40)
toggleButton.Position = UDim2.new(0, 20, 0, 200)
toggleButton.BackgroundColor3 = Color3.fromRGB(40, 40, 40)
toggleButton.BorderSizePixel = 0
toggleButton.Image = "rbxassetid://99842542216672"
toggleButton.Visible = false
toggleButton.Parent = screenGui
applyRoundedCorners(toggleButton)

-- drag logic for toggle button
do
    local dragging = false
    local dragStart, startPos

    toggleButton.InputBegan:Connect(function(input)
        if input.UserInputType == Enum.UserInputType.MouseButton1
            or input.UserInputType == Enum.UserInputType.Touch then

            dragging = true
            dragStart = input.Position
            startPos = toggleButton.Position

            input.Changed:Connect(function()
                if input.UserInputState == Enum.UserInputState.End then
                    dragging = false
                end
            end)
        end
    end)

    toggleButton.InputChanged:Connect(function(input)
        if input.UserInputType == Enum.UserInputType.MouseMovement
            or input.UserInputType == Enum.UserInputType.Touch then

            if dragging then
                local delta = input.Position - dragStart
                toggleButton.Position = UDim2.new(
                    startPos.X.Scale,
                    startPos.X.Offset + delta.X,
                    startPos.Y.Scale,
                    startPos.Y.Offset + delta.Y
                )
            end
        end
    end)
end

-- Main window
local mainFrame = Instance.new("Frame")
mainFrame.Name = "MainFrame"
mainFrame.Size = UDim2.new(0, 460, 0, 380)
mainFrame.Position = UDim2.new(0, 20, 0, 200)
mainFrame.BackgroundColor3 = Color3.fromRGB(30, 30, 30)
mainFrame.BorderSizePixel = 0
mainFrame.Active = true
mainFrame.Draggable = true
mainFrame.Parent = screenGui
applyRoundedCorners(mainFrame)

-- Title bar
local titleBar = Instance.new("Frame")
titleBar.Name = "TitleBar"
titleBar.Size = UDim2.new(1, 0, 0, 28)
titleBar.BackgroundColor3 = Color3.fromRGB(45, 45, 45)
titleBar.BorderSizePixel = 0
titleBar.Parent = mainFrame
applyRoundedCorners(titleBar)

local titleLabel = Instance.new("TextLabel")
titleLabel.Name = "TitleLabel"
titleLabel.Size = UDim2.new(1, -40, 1, 0)
titleLabel.Position = UDim2.new(0, 5, 0, 0)
titleLabel.BackgroundTransparency = 1
titleLabel.Font = Enum.Font.SourceSansBold
titleLabel.TextSize = 18
titleLabel.TextColor3 = Color3.new(1, 1, 1)
titleLabel.TextXAlignment = Enum.TextXAlignment.Left
titleLabel.Text = "Piggy Intercity Infecteds Control | by OOF_Dev"
titleLabel.Parent = titleBar

local minimizeButton = Instance.new("TextButton")
minimizeButton.Name = "MinimizeButton"
minimizeButton.Size = UDim2.new(0, 28, 0, 20)
minimizeButton.Position = UDim2.new(1, -30, 0.5, -10)
minimizeButton.BackgroundColor3 = Color3.fromRGB(60, 60, 60)
minimizeButton.BorderSizePixel = 0
minimizeButton.Font = Enum.Font.SourceSansBold
minimizeButton.TextSize = 18
minimizeButton.TextColor3 = Color3.new(1, 1, 1)
minimizeButton.Text = "-"
minimizeButton.Parent = titleBar
applyRoundedCorners(minimizeButton)

-- Tabs bar
local tabsBar = Instance.new("Frame")
tabsBar.Name = "TabsBar"
tabsBar.Size = UDim2.new(1, -10, 0, 26)
tabsBar.Position = UDim2.new(0, 5, 0, 30)
tabsBar.BackgroundTransparency = 1
tabsBar.Parent = mainFrame

local function createTabButton(name, text, xScale)
    local btn = Instance.new("TextButton")
    btn.Name = name
    btn.Size = UDim2.new(0.33, -5, 1, 0)
    btn.Position = UDim2.new(xScale, 0, 0, 0)
    btn.BackgroundColor3 = Color3.fromRGB(45, 45, 45)
    btn.BorderSizePixel = 0
    btn.Font = Enum.Font.SourceSansBold
    btn.TextSize = 14
    btn.TextColor3 = Color3.new(1, 1, 1)
    btn.Text = text
    btn.Parent = tabsBar
    applyRoundedCorners(btn)
    return btn
end

local mainTabBtn      = createTabButton("MainTabButton",      "Main",      0)
local visualsTabBtn   = createTabButton("VisualsTabButton",   "Visuals",   0.33)
local minigamesTabBtn = createTabButton("MinigamesTabButton", "Minigames", 0.66)

-- Pages
local pagesFrame = Instance.new("Frame")
pagesFrame.Name = "PagesFrame"
pagesFrame.Size = UDim2.new(1, -10, 1, -70)
pagesFrame.Position = UDim2.new(0, 5, 0, 60)
pagesFrame.BackgroundTransparency = 1
pagesFrame.Parent = mainFrame

local function createPage(name)
    local page = Instance.new("Frame")
    page.Name = name
    page.Size = UDim2.new(1, 0, 1, 0)
    page.Position = UDim2.new(0, 0, 0, 0)
    page.BackgroundTransparency = 1
    page.Visible = false
    page.Parent = pagesFrame
    applyRoundedCorners(page)
    return page
end

local mainPage      = createPage("MainPage")
local visualsPage   = createPage("VisualsPage")
local minigamesPage = createPage("MinigamesPage")

-- Discord footer on each page
local function createDiscordFooter(parent)
    local footerFrame = Instance.new("Frame")
    footerFrame.Name = "DiscordFooter"
    footerFrame.Size = UDim2.new(1, -10, 0, 24)
    footerFrame.AnchorPoint = Vector2.new(0, 1)
    footerFrame.Position = UDim2.new(0, 5, 1, -5)
    footerFrame.BackgroundTransparency = 1
    footerFrame.Parent = parent

    local linkLabel = Instance.new("TextLabel")
    linkLabel.Name = "DiscordLinkLabel"
    linkLabel.Size = UDim2.new(1, -90, 1, 0)
    linkLabel.Position = UDim2.new(0, 0, 0, 0)
    linkLabel.BackgroundTransparency = 1
    linkLabel.Font = Enum.Font.SourceSansBold
    linkLabel.TextSize = 14
    linkLabel.TextColor3 = Color3.fromRGB(170, 0, 255)
    linkLabel.TextXAlignment = Enum.TextXAlignment.Left
    linkLabel.Text = "https://discord.gg/E3Nj2JZHaw"
    linkLabel.Parent = footerFrame

    local copyButton = Instance.new("TextButton")
    copyButton.Name = "CopyDiscordButton"
    copyButton.Size = UDim2.new(0, 80, 1, 0)
    copyButton.AnchorPoint = Vector2.new(1, 0)
    copyButton.Position = UDim2.new(1, 0, 0, 0)
    copyButton.BackgroundColor3 = Color3.fromRGB(60, 60, 60)
    copyButton.BorderSizePixel = 0
    copyButton.Font = Enum.Font.SourceSansBold
    copyButton.TextSize = 13
    copyButton.TextColor3 = Color3.new(1, 1, 1)
    copyButton.Text = "Copy"
    copyButton.Parent = footerFrame
    applyRoundedCorners(copyButton)

    copyButton.MouseButton1Click:Connect(function()
        if setclipboard then
            setclipboard("https://discord.gg/E3Nj2JZHaw")
        elseif Clipboard and Clipboard.setClipboard then
            Clipboard.setClipboard("https://discord.gg/E3Nj2JZHaw")
        else
            print("Copy not supported in this environment")
        end
    end)
end

createDiscordFooter(mainPage)
createDiscordFooter(visualsPage)
createDiscordFooter(minigamesPage)

local currentPage = mainPage

local function setActiveTab(page, tabBtn)
    currentPage.Visible = false
    currentPage = page
    currentPage.Visible = true

    for _, btn in ipairs(tabsBar:GetChildren()) do
        if btn:IsA("TextButton") then
            btn.BackgroundColor3 = Color3.fromRGB(45, 45, 45)
        end
    end
    tabBtn.BackgroundColor3 = Color3.fromRGB(70, 70, 70)
end

mainTabBtn.MouseButton1Click:Connect(function()
    setActiveTab(mainPage, mainTabBtn)
end)
visualsTabBtn.MouseButton1Click:Connect(function()
    setActiveTab(visualsPage, visualsTabBtn)
end)
minigamesTabBtn.MouseButton1Click:Connect(function()
    setActiveTab(minigamesPage, minigamesTabBtn)
end)

currentPage.Visible = true
mainTabBtn.BackgroundColor3 = Color3.fromRGB(70, 70, 70)

-- ========= MAIN TAB CONTENT =========

local function createLabel(parent, name, text, pos)
    local lbl = Instance.new("TextLabel")
    lbl.Name = name
    lbl.Size = UDim2.new(0, 100, 0, 18)
    lbl.Position = pos
    lbl.BackgroundTransparency = 1
    lbl.Font = Enum.Font.SourceSans
    lbl.TextSize = 14
    lbl.TextColor3 = Color3.fromRGB(220, 220, 220)
    lbl.TextXAlignment = Enum.TextXAlignment.Left
    lbl.Text = text
    lbl.Parent = parent
    return lbl
end

local function createTextBox(parent, name, text, pos, sizeX)
    local tb = Instance.new("TextBox")
    tb.Name = name
    tb.Size = UDim2.new(0, sizeX, 0, 20)
    tb.Position = pos
    tb.BackgroundColor3 = Color3.fromRGB(45, 45, 45)
    tb.BorderSizePixel = 0
    tb.Font = Enum.Font.SourceSans
    tb.TextSize = 14
    tb.TextColor3 = Color3.new(1, 1, 1)
    tb.ClearTextOnFocus = false
    tb.Text = text
    tb.Parent = parent
    applyRoundedCorners(tb)
    return tb
end

createLabel(mainPage, "ScaleLabel", "Hitbox Scale x:", UDim2.new(0, 5, 0, 5))
local scaleBox = createTextBox(mainPage, "ScaleBox", tostring(DEFAULT_HITBOX_SCALE), UDim2.new(0, 110, 0, 5), 50)

createLabel(mainPage, "OffsetLabel", "Offset Z:", UDim2.new(0, 5, 0, 30))
local offsetBox = createTextBox(mainPage, "OffsetBox", tostring(DEFAULT_OFFSET_Z), UDim2.new(0, 90, 0, 30), 60)

createLabel(mainPage, "DelayLabel", "Delay (s):", UDim2.new(0, 170, 0, 5))
local delayBox = createTextBox(mainPage, "DelayBox", tostring(DEFAULT_UPDATE_DELAY), UDim2.new(0, 250, 0, 5), 60)

createLabel(mainPage, "SpeedLabel", "Speed:", UDim2.new(0, 5, 0, 55))
local speedBox = createTextBox(mainPage, "SpeedBox", tostring(DEFAULT_SPEED), UDim2.new(0, 90, 0, 55), 60)

createLabel(mainPage, "JumpLabel", "JumpPower:", UDim2.new(0, 170, 0, 55))
local jumpBox = createTextBox(mainPage, "JumpBox", tostring(DEFAULT_JUMP), UDim2.new(0, 250, 0, 55), 60)

-- switches + flags
local reachEnabled, resizeEnabled = false, false
local speedEnabled, jumpEnabled   = false, false
local noclipEnabled, infJumpEnabled = false, false

local reachSwitch   = createToggleSwitch(mainPage, "ReachSwitch",   "Reach",    UDim2.new(0,   5, 0, 90))
local resizeSwitch  = createToggleSwitch(mainPage, "ResizeSwitch",  "Resize",   UDim2.new(0.5, 5, 0, 90))
local speedSwitch   = createToggleSwitch(mainPage, "SpeedSwitch",   "Speed",    UDim2.new(0,   5, 0, 120))
local jumpSwitch    = createToggleSwitch(mainPage, "JumpSwitch",    "Jump",     UDim2.new(0.5, 5, 0, 120))
local noclipSwitch  = createToggleSwitch(mainPage, "NoclipSwitch",  "Noclip",   UDim2.new(0,   5, 0, 150))
local infJumpSwitch = createToggleSwitch(mainPage, "InfJumpSwitch", "Inf Jump", UDim2.new(0.5, 5, 0, 150))

reachSwitch.OnToggle(function(s)   reachEnabled   = s end)
resizeSwitch.OnToggle(function(s)  resizeEnabled  = s end)
speedSwitch.OnToggle(function(s)   speedEnabled   = s end)
jumpSwitch.OnToggle(function(s)    jumpEnabled    = s end)
noclipSwitch.OnToggle(function(s)  noclipEnabled  = s end)
infJumpSwitch.OnToggle(function(s) infJumpEnabled = s end)

-- ========= VISUALS TAB CONTENT =========

local visualsLabel = Instance.new("TextLabel")
visualsLabel.Name = "VisualsInfo"
visualsLabel.Size = UDim2.new(1, -10, 0, 18)
visualsLabel.Position = UDim2.new(0, 5, 0, 5)
visualsLabel.BackgroundTransparency = 1
visualsLabel.Font = Enum.Font.SourceSans
visualsLabel.TextSize = 14
visualsLabel.TextColor3 = Color3.fromRGB(220, 220, 220)
visualsLabel.TextXAlignment = Enum.TextXAlignment.Left
visualsLabel.Text = "Visuals:"
visualsLabel.Parent = visualsPage

local highlightEnabled, lootEspEnabled = false, false
local materialsEspEnabled = false

local espSwitch     = createToggleSwitch(visualsPage, "EnemiesESPSwitch",    "Enemies ESP",    UDim2.new(0,   5, 0, 30))
local lootEspSwitch = createToggleSwitch(visualsPage, "LootcratesESPSwitch", "Lootcrates ESP", UDim2.new(0.5, 5, 0, 30))
local materialsEspSwitch = createToggleSwitch(visualsPage, "MaterialsESPSwitch", "Materials ESP", UDim2.new(0, 5, 0, 60))

espSwitch.OnToggle(function(s)     highlightEnabled   = s end)
lootEspSwitch.OnToggle(function(s) lootEspEnabled     = s end)
materialsEspSwitch.OnToggle(function(s) materialsEspEnabled = s end)

-- ========= MINIGAMES TAB CONTENT =========

local golfLabel = Instance.new("TextLabel")
golfLabel.Name = "GolfLabel"
golfLabel.Size = UDim2.new(1, -10, 0, 18)
golfLabel.Position = UDim2.new(0, 5, 0, 5)
golfLabel.BackgroundTransparency = 1
golfLabel.Font = Enum.Font.SourceSans
golfLabel.TextSize = 14
golfLabel.TextColor3 = Color3.fromRGB(220, 220, 220)
golfLabel.TextXAlignment = Enum.TextXAlignment.Left
golfLabel.Text = "Golf Center TP (all lanes):"
golfLabel.Parent = minigamesPage

local function createGolfButton(name, text, pos)
    local btn = Instance.new("TextButton")
    btn.Name = name
    btn.Size = UDim2.new(0.5, -15, 0, 25)
    btn.Position = pos
    btn.BackgroundColor3 = Color3.fromRGB(40, 40, 40)
    btn.BorderSizePixel = 0
    btn.Font = Enum.Font.SourceSansBold
    btn.TextSize = 14
    btn.TextColor3 = Color3.new(1, 1, 1)
    btn.Text = text
    btn.Parent = minigamesPage
    applyRoundedCorners(btn)
    return btn
end

local greenBtn  = createGolfButton("GreenBtn",  "Green Center",  UDim2.new(0,   5, 0, 30))
local blueBtn   = createGolfButton("BlueBtn",   "Blue Center",   UDim2.new(0.5, 10, 0, 30))
local redBtn    = createGolfButton("RedBtn",    "Red Center",    UDim2.new(0,   5, 0, 60))
local purpleBtn = createGolfButton("PurpleBtn", "Purple Center", UDim2.new(0.5, 10, 0, 60))

-- manual center TP (you can later wire these if you want same behavior as old script)
greenBtn.MouseButton1Click:Connect(function()
    -- left for manual behavior if you want
end)
blueBtn.MouseButton1Click:Connect(function()
end)
redBtn.MouseButton1Click:Connect(function()
end)
purpleBtn.MouseButton1Click:Connect(function()
end)

-- ========= AUTOGOLF (exact version you sent) =========

local autoGolfEnabled = false
local AUTO_GOLF_LOOP_DELAY = 0.05

local autoGolfTargetOrder = {
    "Target_Blue",
    "Target_Green",
    "Target_Red",
    "Target_Purple",
    "Target_Yellow"
}

local function getFirstValidAutoGolfTarget(lane)
    local targets = lane:FindFirstChild("Targets")
    if not targets then return nil, nil end

    for _, name in ipairs(autoGolfTargetOrder) do
        local model = targets:FindFirstChild(name)
        if model and model:IsA("Model") then
            local centerRing = model:FindFirstChild("CenterRing")
            if centerRing and centerRing:IsA("BasePart") then
                return model, centerRing
            end
        end
    end

    return nil, nil
end

local function autoGolfStep()
    for _, lane in ipairs(LANES_FOLDER:GetChildren()) do
        if not lane:IsA("Folder") then
            continue
        end

        local ball = lane:FindFirstChild("GolfBall")
        if not (ball and ball:IsA("MeshPart")) then
            continue
        end

        local _, centerRing = getFirstValidAutoGolfTarget(lane)
        if not centerRing then
            continue
        end

        local newPos = centerRing.Position + Vector3.new(0, ball.Size.Y * 0.5 + 0.05, 0)
        ball.CFrame = CFrame.new(newPos)
    end
end

task.spawn(function()
    while true do
        if autoGolfEnabled then
            autoGolfStep()
        end
        task.wait(AUTO_GOLF_LOOP_DELAY)
    end
end)

local autoGolfSwitch = createToggleSwitch(minigamesPage, "AutoGolfSwitch", "AutoGolf", UDim2.new(0, 5, 0, 95))
autoGolfSwitch.OnToggle(function(s) autoGolfEnabled = s end)

-- ========= BOWLING CONFIG + TOGGLE =========

local BOWLING_PATH = Workspace:WaitForChild("Interiors")
    :WaitForChild("Meerkat Bowling")
    :WaitForChild("Minigame")
local BOWLING_LANES = BOWLING_PATH:WaitForChild("Lanes")

local bowlingLaneData = {
    Lane1 = {
        lanePos   = Vector3.new(-3310.79395, -223.11998, 756.515381),
        playerPos = Vector3.new(-3319.19409, -223.11998, 756.715332),
    },
    Lane2 = {
        lanePos   = Vector3.new(-3310.79395, -223.11998, 767.415405),
        playerPos = Vector3.new(-3319.19409, -223.11998, 767.615356),
    },
    Lane3 = {
        lanePos   = Vector3.new(-3310.79395, -223.11998, 778.415405),
        playerPos = Vector3.new(-3319.19409, -223.11998, 778.615356),
    },
    Lane4 = {
        lanePos   = Vector3.new(-3310.79395, -223.11998, 789.515381),
        playerPos = Vector3.new(-3319.19409, -223.11998, 789.515381),
    },
}

local bowlingEnabled = false
local bowlingAimPart = nil
local currentBowlingLaneName = nil
local prevNoclipState = false

local bowlingSwitch = createToggleSwitch(
    minigamesPage,
    "BowlingSwitch",
    "Bowling",
    UDim2.new(0.5, 5, 0, 95)
)

local function getChar()
    return LocalPlayer.Character or LocalPlayer.CharacterAdded:Wait()
end

local function getMyHRP()
    local char = getChar()
    return char:FindFirstChild("HumanoidRootPart")
end

local function getMyHumanoid()
    local char = getChar()
    return char:FindFirstChildOfClass("Humanoid")
end

local function getBowlingHRP()
    return getMyHRP()
end

local function getActiveBowlingLane()
    for laneName, _ in pairs(bowlingLaneData) do
        local laneFolder = BOWLING_LANES:FindFirstChild(laneName)
        if laneFolder and laneFolder:IsA("Folder") then
            local barriers = laneFolder:FindFirstChild("Barriers", true)
            if barriers then
                return laneName, laneFolder
            end
        end
    end
    return nil, nil
end

local function ensureBowlingAimPart(laneName)
    local laneInfo = bowlingLaneData[laneName]
    if not laneInfo then return end

    if not bowlingAimPart or not bowlingAimPart.Parent then
        bowlingAimPart = Instance.new("Part")
        bowlingAimPart.Name = "BowlingAimPart"
        bowlingAimPart.Size = Vector3.new(0.1, 0.1, 0.1)
        bowlingAimPart.Anchored = true
        bowlingAimPart.CanCollide = false
        bowlingAimPart.Transparency = 1
        bowlingAimPart.Parent = Workspace
    end

    bowlingAimPart.CFrame = CFrame.new(laneInfo.lanePos)
end

local function teleportPlayerToBowlingLane(laneName)
    local laneInfo = bowlingLaneData[laneName]
    if not laneInfo then return end

    local hrp = getBowlingHRP()
    if not hrp then return end

    hrp.CFrame = CFrame.new(laneInfo.playerPos)
end

local function enableBowlingOnce()
    if bowlingEnabled then return end
    bowlingEnabled = true

    prevNoclipState = noclipEnabled
    noclipEnabled = true

    local laneName, _ = getActiveBowlingLane()
    if laneName then
        currentBowlingLaneName = laneName
        ensureBowlingAimPart(laneName)
        teleportPlayerToBowlingLane(laneName)
    else
        bowlingEnabled = false
        noclipEnabled = prevNoclipState
        if bowlingAimPart and bowlingAimPart.Parent then
            bowlingAimPart:Destroy()
        end
        bowlingAimPart = nil
        currentBowlingLaneName = nil
    end
end

local function disableBowling()
    if not bowlingEnabled then return end
    bowlingEnabled = false
    noclipEnabled = prevNoclipState

    if bowlingAimPart and bowlingAimPart.Parent then
        bowlingAimPart:Destroy()
    end
    bowlingAimPart = nil
    currentBowlingLaneName = nil
end

bowlingSwitch.OnToggle(function(s)
    if s then
        enableBowlingOnce()
    else
        disableBowling()
    end
end)

-- ========= SETTINGS APPLY =========

local function applySettings()
    local s = tonumber(scaleBox.Text)
    if s and s > 0 then
        HITBOX_SCALE = s
    else
        HITBOX_SCALE = DEFAULT_HITBOX_SCALE
        scaleBox.Text = tostring(DEFAULT_HITBOX_SCALE)
    end

    local z = tonumber(offsetBox.Text)
    if z then
        OFFSET = CFrame.new(0, 0, z)
    else
        OFFSET = CFrame.new(0, 0, DEFAULT_OFFSET_Z)
        offsetBox.Text = tostring(DEFAULT_OFFSET_Z)
    end

    local d = tonumber(delayBox.Text)
    if d and d > 0 then
        UPDATE_DELAY = d
    else
        UPDATE_DELAY = DEFAULT_UPDATE_DELAY
        delayBox.Text = tostring(DEFAULT_UPDATE_DELAY)
    end

    local sp = tonumber(speedBox.Text)
    if sp and sp > 0 then
        SPEED_VALUE = sp
    else
        SPEED_VALUE = DEFAULT_SPEED
        speedBox.Text = tostring(DEFAULT_SPEED)
    end

    local jp = tonumber(jumpBox.Text)
    if jp and jp > 0 then
        JUMP_VALUE = jp
    else
        JUMP_VALUE = DEFAULT_JUMP
        jumpBox.Text = tostring(DEFAULT_JUMP)
    end
end

scaleBox.FocusLost:Connect(function(enterPressed) if enterPressed then applySettings() end end)
offsetBox.FocusLost:Connect(function(enterPressed) if enterPressed then applySettings() end end)
delayBox.FocusLost:Connect(function(enterPressed) if enterPressed then applySettings() end end)
speedBox.FocusLost:Connect(function(enterPressed) if enterPressed then applySettings() end end)
jumpBox.FocusLost:Connect(function(enterPressed) if enterPressed then applySettings() end end)

-- ========= ENEMY ESP + MAIN NPC LOOP =========

local cachedNPCModels = {}
local originalProps = {}
local origWalkSpeed, origJumpPower

local function cacheModelProps(mdl)
    for _, p in ipairs(mdl:GetDescendants()) do
        if p:IsA("BasePart") and not originalProps[p] then
            originalProps[p] = {
                Size = p.Size,
                Color = p.Color,
                Transparency = p.Transparency,
            }
        end
    end
end

local function rebuildCache()
    table.clear(cachedNPCModels)
    local npcFolder = Workspace:FindFirstChild(NPC_FOLDER_NAME)
    if not npcFolder then return end
    for _, mdl in ipairs(npcFolder:GetChildren()) do
        if mdl:IsA("Model") and VALID_NPC_NAMES[mdl.Name] then
            table.insert(cachedNPCModels, mdl)
            cacheModelProps(mdl)
        end
    end
end

rebuildCache()

local highlights = {}
local nameTags = {}

local function createNameTag(mdl)
    if nameTags[mdl] then return nameTags[mdl] end

    local hrp = mdl:FindFirstChild("HumanoidRootPart")
        or mdl:FindFirstChild("Torso")
        or mdl:FindFirstChildOfClass("BasePart")
    if not hrp then return nil end

    local bill = Instance.new("BillboardGui")
    bill.Name = "EnemyNameTag"
    bill.Size = UDim2.new(0, 160, 0, 30)
    bill.StudsOffset = Vector3.new(0, 4, 0)
    bill.AlwaysOnTop = true
    bill.Adornee = hrp
    bill.Parent = mdl

    local txt = Instance.new("TextLabel")
    txt.Size = UDim2.new(1, 0, 1, 0)
    txt.BackgroundTransparency = 1
    txt.Font = Enum.Font.SourceSansBold
    txt.TextSize = 16

    local name = mdl.Name
    if string.find(name, "Infected") then
        txt.TextColor3 = Color3.fromRGB(0, 255, 0)
    elseif string.find(name, "Bandit") then
        txt.TextColor3 = Color3.fromRGB(255, 0, 0)
    else
        txt.TextColor3 = Color3.fromRGB(0, 170, 255)
    end

    txt.Text = mdl.Name .. " (HP)"
    txt.Parent = bill

    txt.TextStrokeTransparency = 0
    txt.TextStrokeColor3 = Color3.fromRGB(0, 0, 0)

    nameTags[mdl] = bill
    return bill
end

local function removeVisualsForModel(mdl)
    if highlights[mdl] then
        highlights[mdl]:Destroy()
        highlights[mdl] = nil
    end
    if nameTags[mdl] then
        nameTags[mdl]:Destroy()
        nameTags[mdl] = nil
    end
end

local function clearEnemyESP()
    for mdl, _ in pairs(highlights) do
        removeVisualsForModel(mdl)
    end
end

espSwitch.OnToggle(function(s)
    highlightEnabled = s
    if not highlightEnabled then
        clearEnemyESP()
    end
end)

-- MAIN INFECTED LOOP
task.spawn(function()
    local lastRebuild = 0

    while true do
        task.wait(UPDATE_DELAY)

        local now = tick()
        if now - lastRebuild > 3 then
            rebuildCache()
            lastRebuild = now
        end

        local hum = getMyHumanoid()
        if hum then
            if speedEnabled then
                if not origWalkSpeed then
                    origWalkSpeed = hum.WalkSpeed
                end
                hum.WalkSpeed = SPEED_VALUE
            elseif origWalkSpeed then
                hum.WalkSpeed = origWalkSpeed
            end

            if jumpEnabled then
                if not origJumpPower then
                    origJumpPower = hum.JumpPower
                end
                hum.JumpPower = JUMP_VALUE
            elseif origJumpPower then
                hum.JumpPower = origJumpPower
            end
        end

        if not (reachEnabled or resizeEnabled or highlightEnabled) then
            continue
        end

        local myHrp = getMyHRP()
        if myHrp then
            local targetCF = myHrp.CFrame * OFFSET

            for _, mdl in ipairs(cachedNPCModels) do
                if mdl and mdl.Parent then
                    local npcHum = mdl:FindFirstChildOfClass("Humanoid")

                    if npcHum and npcHum.Health <= 0 then
                        mdl:PivotTo(OBLIVION_CFRAME)
                        removeVisualsForModel(mdl)
                        continue
                    end

                    if highlightEnabled then
                        if not highlights[mdl] then
                            local hl = Instance.new("Highlight")
                            hl.FillTransparency = 0.3
                            hl.FillColor = Color3.fromRGB(255, 0, 0)
                            hl.OutlineTransparency = 0
                            hl.OutlineColor = Color3.fromRGB(255, 255, 255)
                            hl.DepthMode = Enum.HighlightDepthMode.AlwaysOnTop
                            hl.Adornee = mdl
                            hl.Parent = mdl
                            highlights[mdl] = hl
                        end

                        local tag = createNameTag(mdl)
                        if tag and npcHum then
                            local label = tag:FindFirstChildOfClass("TextLabel")
                            if label then
                                label.Text = string.format("%s (%.0f HP)", mdl.Name, npcHum.Health)
                            end
                        end
                    else
                        removeVisualsForModel(mdl)
                    end

                    if reachEnabled then
                        mdl:PivotTo(targetCF)
                    end

                    if resizeEnabled then
                        for _, p in ipairs(mdl:GetDescendants()) do
                            if p:IsA("BasePart") then
                                local props = originalProps[p]
                                if props then
                                    p.Size = props.Size * HITBOX_SCALE
                                    p.Transparency = 0
                                    p.Color = Color3.new(1, 0, 0)
                                end
                                if p.Name == "HumanoidRootPart" then
                                    p.Color = Color3.new(1, 0, 0)
                                    p.Transparency = 0.5
                                end
                            end
                        end
                    end
                end
            end
        end
    end
end)

-- ========= LOOTCRATES ESP =========

local lootcrateHighlights = {}
local lootcrateTags = {}
local lootcrateIndex = {} 

local LOOT_REFRESH_DELAY = 1.5

local function clearLootcrateHighlights()
    for crateModel, data in pairs(lootcrateIndex) do
        if data.Highlight and data.Highlight.Parent then
            data.Highlight:Destroy()
        end
        if data.Tag and data.Tag.Parent then
            data.Tag:Destroy()
        end
        lootcrateIndex[crateModel] = nil
    end

    for _, hl in ipairs(lootcrateHighlights) do
        if hl and hl.Parent then
            hl:Destroy()
        end
    end
    for _, gui in ipairs(lootcrateTags) do
        if gui and gui.Parent then
            gui:Destroy()
        end
    end
    table.clear(lootcrateHighlights)
    table.clear(lootcrateTags)
end

local function makeLootcrateTag(part, text, color)
    if not part or not part.Parent then return nil end

    local bill = Instance.new("BillboardGui")
    bill.Name = "LootcrateTag"
    bill.Size = UDim2.new(0, 120, 0, 24)
    bill.StudsOffset = Vector3.new(0, 3, 0)
    bill.AlwaysOnTop = true
    bill.Adornee = part
    bill.Parent = part

    local lbl = Instance.new("TextLabel")
    lbl.Size = UDim2.new(1, 0, 1, 0)
    lbl.BackgroundTransparency = 1
    lbl.Font = Enum.Font.SourceSansBold
    lbl.TextSize = 14
    lbl.TextColor3 = color
    lbl.TextStrokeTransparency = 0
    lbl.TextStrokeColor3 = Color3.fromRGB(0, 0, 0)
    lbl.Text = text
    lbl.Parent = bill

    table.insert(lootcrateTags, bill)
    return bill
end

local function getAnyBasePartFromModel(m)
    if not m then return nil end
    if m.PrimaryPart and m.PrimaryPart:IsA("BasePart") then
        return m.PrimaryPart
    end
    for _, d in ipairs(m:GetDescendants()) do
        if d:IsA("BasePart") then
            return d
        end
    end
    return nil
end

local function ensureLootcrateVisual(crateModel)
    if not crateModel or not crateModel:IsA("Model") then return end
    if lootcrateIndex[crateModel] then return end

    local primary = getAnyBasePartFromModel(crateModel)
    if not primary then return end

    local isPermanent = (crateModel.Name == "Permanent")

    local hl = Instance.new("Highlight")
    hl.Name = "LootcrateHighlight"
    hl.FillColor = isPermanent and Color3.fromRGB(170, 0, 255) or Color3.fromRGB(255, 230, 0)
    hl.FillTransparency = 0.4
    hl.OutlineColor = Color3.fromRGB(255, 255, 255)
    hl.OutlineTransparency = 0
    hl.DepthMode = Enum.HighlightDepthMode.AlwaysOnTop
    hl.Adornee = crateModel
    hl.Parent = Workspace

    table.insert(lootcrateHighlights, hl)

    local tag = makeLootcrateTag(
        primary,
        isPermanent and "One Time Lootcrate" or "Lootcrate",
        isPermanent and Color3.fromRGB(170, 0, 255) or Color3.fromRGB(255, 230, 0)
    )

    lootcrateIndex[crateModel] = {
        Highlight = hl,
        Tag = tag
    }
end

local function scanLootFolder(folder)
    if not folder or not folder:IsA("Folder") then return end
    for _, crate in ipairs(folder:GetChildren()) do
        if crate:IsA("Model") then
            ensureLootcrateVisual(crate)
        end
    end
end

local function scanMapLootcrates(mapModel)
    if not mapModel or not mapModel:IsA("Model") then return end

    local lootFolder = mapModel:FindFirstChild("Lootcrates")
    if lootFolder and lootFolder:IsA("Folder") then
        scanLootFolder(lootFolder)
    end
end

local function removeMissingLootcrateVisuals()
    for crateModel, data in pairs(lootcrateIndex) do
        if not crateModel or not crateModel.Parent then
            if data.Highlight and data.Highlight.Parent then
                data.Highlight:Destroy()
            end
            if data.Tag and data.Tag.Parent then
                data.Tag:Destroy()
            end
            lootcrateIndex[crateModel] = nil
        end
    end
end

local function updateLootcratesESP()
    if not lootEspEnabled then return end

    local locationsRoot = Workspace:FindFirstChild("Locations")
    local interiorsRoot = Workspace:FindFirstChild("Interiors")

    if locationsRoot then
        for _, map in ipairs(locationsRoot:GetChildren()) do
            if map:IsA("Model") then
                scanMapLootcrates(map)
            end
        end
    end

    if interiorsRoot then
        for _, map in ipairs(interiorsRoot:GetChildren()) do
            if map:IsA("Model") then
                scanMapLootcrates(map)
            end
        end
    end

    removeMissingLootcrateVisuals()
end

lootEspSwitch.OnToggle(function(state)
    lootEspEnabled = state
    if not lootEspEnabled then
        clearLootcrateHighlights()
    else
        updateLootcratesESP()
    end
end)

task.spawn(function()
    while true do
        if lootEspEnabled then
            updateLootcratesESP()
        end
        task.wait(LOOT_REFRESH_DELAY)
    end
end)

-- ========= MATERIALS ESP =========

local materialsHighlights = {}
local materialsTags = {}
local materialsIndex = {} 

local MATERIALS_REFRESH_DELAY = 2

local ORE_NAMES = {
    Stone = true,
    Iron = true,
    Bauxite = true,
    Coal = true,
}

local TERRAIN_NAMES = {
    Dirt = true,
    Grass = true,
    Sand = true,
}

local PLANT_NAMES = {
    Tree = true,
    CottonPlant = true,
}

local function clearMaterialsESP()
    for mdl, data in pairs(materialsIndex) do
        if data.Highlights then
            for _, hl in ipairs(data.Highlights) do
                if hl and hl.Parent then
                    hl:Destroy()
                end
            end
        end
        if data.Tag and data.Tag.Parent then
            data.Tag:Destroy()
        end
        materialsIndex[mdl] = nil
    end

    for _, hl in ipairs(materialsHighlights) do
        if hl and hl.Parent then
            hl:Destroy()
        end
    end
    for _, gui in ipairs(materialsTags) do
        if gui and gui.Parent then
            gui:Destroy()
        end
    end
    table.clear(materialsHighlights)
    table.clear(materialsTags)
end

local function makeMaterialTag(part, text)
    if not part or not part.Parent then return nil end

    local bill = Instance.new("BillboardGui")
    bill.Name = "MaterialTag"
    bill.Size = UDim2.new(0, 120, 0, 24)
    bill.StudsOffset = Vector3.new(0, 3, 0)
    bill.AlwaysOnTop = true
    bill.Adornee = part
    bill.Parent = part

    local lbl = Instance.new("TextLabel")
    lbl.Size = UDim2.new(1, 0, 1, 0)
    lbl.BackgroundTransparency = 1
    lbl.Font = Enum.Font.SourceSansBold
    lbl.TextSize = 14
    lbl.TextColor3 = Color3.new(1, 1, 1)
    lbl.TextStrokeTransparency = 0
    lbl.TextStrokeColor3 = Color3.fromRGB(0, 0, 0)
    lbl.Text = text
    lbl.Parent = bill

    table.insert(materialsTags, bill)
    return bill
end

local function addHighlightToParts(partsTable)
    local created = {}

    for _, part in ipairs(partsTable) do
        if part and part:IsA("BasePart") then
            local hl = Instance.new("Highlight")
            hl.Name = "MaterialHighlight"
            hl.FillColor = Color3.new(1, 1, 1)
            hl.FillTransparency = 0.4
            hl.OutlineColor = Color3.new(1, 1, 1)
            hl.OutlineTransparency = 0
            hl.DepthMode = Enum.HighlightDepthMode.AlwaysOnTop
            hl.Adornee = part
            hl.Parent = Workspace

            table.insert(materialsHighlights, hl)
            table.insert(created, hl)
        end
    end

    return created
end

local function ensureMaterialVisual(matModel)
    if not matModel or not matModel:IsA("Model") then return end
    if materialsIndex[matModel] then return end

    local modelName = matModel.Name
    local targets = {}

    if ORE_NAMES[modelName] then
        local base = matModel:FindFirstChild("Base")
        if base and base:IsA("MeshPart") then
            table.insert(targets, base)
        end

        if modelName ~= "Stone" then
            local crystals = matModel:FindFirstChild("Crystals")
            if crystals and crystals:IsA("MeshPart") then
                table.insert(targets, crystals)
            end
        end

    elseif TERRAIN_NAMES[modelName] then
        local base = matModel:FindFirstChild("Base")
        if base and base:IsA("MeshPart") then
            table.insert(targets, base)
        end

    elseif PLANT_NAMES[modelName] then
        local base = matModel:FindFirstChild("Base")
        local leaves = matModel:FindFirstChild("Leaves")
        if base and base:IsA("MeshPart") then
            table.insert(targets, base)
        end
        if leaves and leaves:IsA("MeshPart") then
            table.insert(targets, leaves)
        end
    else
        return
    end

    if #targets == 0 then return end

    local highlightsForThis = addHighlightToParts(targets)
    if #highlightsForThis == 0 then return end

    local tag = makeMaterialTag(targets[1], modelName)

    materialsIndex[matModel] = {
        Highlights = highlightsForThis,
        Tag = tag,
    }
end

local function scanElementFolder(folder)
    if not folder or not folder:IsA("Folder") then return end
    for _, element in ipairs(folder:GetChildren()) do
        if element:IsA("Model") then
            ensureMaterialVisual(element)
        end
    end
end

local function scanGatherableMaterials()
    local root = Workspace:FindFirstChild("GatherableMaterials")
    if not root then return end

    for _, subFolder in ipairs(root:GetChildren()) do
        if subFolder:IsA("Folder") then
            scanElementFolder(subFolder)
        end
    end
end

local function pruneMissingMaterials()
    for mdl, data in pairs(materialsIndex) do
        if not mdl or not mdl.Parent then
            if data.Highlights then
                for _, hl in ipairs(data.Highlights) do
                    if hl and hl.Parent then
                        hl:Destroy()
                    end
                end
            end
            if data.Tag and data.Tag.Parent then
                data.Tag:Destroy()
            end
            materialsIndex[mdl] = nil
        end
    end
end

local function updateMaterialsESP()
    if not materialsEspEnabled then return end
    scanGatherableMaterials()
    pruneMissingMaterials()
end

materialsEspSwitch.OnToggle(function(state)
    materialsEspEnabled = state
    if not materialsEspEnabled then
        clearMaterialsESP()
    else
        updateMaterialsESP()
    end
end)

task.spawn(function()
    while true do
        if materialsEspEnabled then
            updateMaterialsESP()
        end
        task.wait(MATERIALS_REFRESH_DELAY)
    end
end)

-- ========= Noclip + Inf Jump =========

task.spawn(function()
    while true do
        RunService.Stepped:Wait()
        if noclipEnabled then
            local char = LocalPlayer.Character
            if char then
                for _, part in ipairs(char:GetDescendants()) do
                    if part:IsA("BasePart") and part.CanCollide then
                        part.CanCollide = false
                    end
                end
            end
        end
    end
end)

UserInputService.JumpRequest:Connect(function()
    if infJumpEnabled then
        local hum = getMyHumanoid()
        if hum then
            hum:ChangeState(Enum.HumanoidStateType.Jumping)
        end
    end
end)

-- ========= GUI VISIBILITY + KEYBINDS =========

local guiVisible = true

local function setGuiVisible(state)
    guiVisible = state
    mainFrame.Visible = guiVisible
    toggleButton.Visible = not guiVisible
end

minimizeButton.MouseButton1Click:Connect(function()
    setGuiVisible(not guiVisible)
end)
toggleButton.MouseButton1Click:Connect(function()
    setGuiVisible(true)
end)

UserInputService.InputBegan:Connect(function(input, processed)
    if processed then return end

    if input.KeyCode == Enum.KeyCode.RightShift then
        setGuiVisible(not guiVisible)
    elseif input.KeyCode == Enum.KeyCode.RightAlt then
        if bowlingEnabled then
            bowlingSwitch.Set(false)
            disableBowling()
        else
            bowlingSwitch.Set(true)
            enableBowlingOnce()
        end
    end
end)

-- Thank OOF_Dev for the script ! :)

Features & Information

Credit to OOF_DEV DISCORD : https://discord.gg/E3Nj2JZHaw

Community Comments (0)

No comments yet for this script.

More Scripts for Piggy: Intercity [TREETOPS + DAILY QUESTS]