--[[ ███████╗███████╗ █████╗ ██╗ ██╔════╝██╔════╝██╔══██╗██║ █████╗ █████╗ ███████║██║ ██╔══╝ ██╔══╝ ██╔══██║██║ ██║ ██║ ██║ ██║███████╗ ╚═╝ ╚═╝ ╚═╝ ╚═╝╚══════╝ FCAL HUB - Client Sided Version: 1.0.6 --]] -- Services local Players = game:GetService("Players") local TeleportService = game:GetService("TeleportService") local RunService = game:GetService("RunService") local Lighting = game:GetService("Lighting") local UserInputService = game:GetService("UserInputService") local Workspace = game:GetService("Workspace") local ReplicatedStorage = game:GetService("ReplicatedStorage") local LocalPlayer = Players.LocalPlayer -- Config local Config = { WalkSpeedDefault = 16, JumpPowerDefault = 50, GravityDefault = 196, Theme = "Midnight", FlySpeed = 100, FlySpeedDefault = 100, } -- Load Modal UI local Modal = loadstring(game:HttpGet("https://github.com/BloxCrypto/Modal/releases/download/v1.0-beta/main.lua"))() -- Create Window local Window = Modal:CreateWindow({ Title = "FCAL HUB", SubTitle = "v1.0.6 | Client Sided", Size = UDim2.fromOffset(500, 420), MinimumSize = Vector2.new(350, 300), Transparency = 0, Icon = "rbxassetid://68073547", }) Window:SetTheme(Config.Theme) -- UI Element References (for syncing) local UIElements = { WalkSpeedSlider = nil, WalkSpeedInput = nil, JumpPowerSlider = nil, JumpPowerInput = nil, GravitySlider = nil, GravityInput = nil, FlySpeedSlider = nil, FlySpeedInput = nil, } -- Helpers local function Notify(title, desc, typ) Window:Notify({Title = title, Description = desc, Duration = 3, Type = typ or "Info"}) end local function GetHumanoid() local char = LocalPlayer.Character return char and char:FindFirstChildOfClass("Humanoid") end local function GetRootPart() local char = LocalPlayer.Character return char and char:FindFirstChild("HumanoidRootPart") end local function GetPlayerByName(name) name = name:lower() for _, p in pairs(Players:GetPlayers()) do if p.Name:lower():sub(1, #name) == name or p.DisplayName:lower():sub(1, #name) == name then return p end end return nil end -- Update UI Elements (Sync sliders and inputs) local function UpdateWalkSpeedUI(value) if UIElements.WalkSpeedSlider then pcall(function() UIElements.WalkSpeedSlider:Set(value) end) end if UIElements.WalkSpeedInput then pcall(function() UIElements.WalkSpeedInput:Set(tostring(value)) end) end end local function UpdateJumpPowerUI(value) if UIElements.JumpPowerSlider then pcall(function() UIElements.JumpPowerSlider:Set(value) end) end if UIElements.JumpPowerInput then pcall(function() UIElements.JumpPowerInput:Set(tostring(value)) end) end end local function UpdateGravityUI(value) if UIElements.GravitySlider then pcall(function() UIElements.GravitySlider:Set(value) end) end if UIElements.GravityInput then pcall(function() UIElements.GravityInput:Set(tostring(value)) end) end end local function UpdateFlySpeedUI(value) if UIElements.FlySpeedSlider then pcall(function() UIElements.FlySpeedSlider:Set(value) end) end if UIElements.FlySpeedInput then pcall(function() UIElements.FlySpeedInput:Set(tostring(value)) end) end end -- Role Detection local function GetPlayerRole(player) local inGame = false local gameGui = LocalPlayer:FindFirstChild("PlayerGui") if gameGui then for _, gui in pairs(gameGui:GetChildren()) do if gui.Name:lower():find("game") or gui.Name:lower():find("match") or gui.Name:lower():find("survive") or gui.Name:lower():find("ingame") then if gui.Enabled then inGame = true break end end end end if not inGame then for _, obj in pairs(Workspace:GetChildren()) do if obj.Name:lower():find("generator") or obj.Name:lower():find("gate") or obj.Name:lower():find("survivor") or obj.Name:lower():find("killer") then inGame = true break end end end if not inGame then return "Neutral" end local character = player.Character if not character then return "Neutral" end if player:GetAttribute("Role") then local role = player:GetAttribute("Role") if type(role) == "string" then if role:lower():find("killer") then return "Killer" end if role:lower():find("survivor") or role:lower():find("survive") then return "Survivor" end end end if player:GetAttribute("IsKiller") then return "Killer" end if player:GetAttribute("IsSurvivor") then return "Survivor" end if character:GetAttribute("Role") then local role = character:GetAttribute("Role") if type(role) == "string" then if role:lower():find("killer") then return "Killer" end if role:lower():find("survivor") or role:lower():find("survive") then return "Survivor" end end end if character:GetAttribute("IsKiller") then return "Killer" end if character:GetAttribute("IsSurvivor") then return "Survivor" end local roleValue = character:FindFirstChild("Role") if roleValue and roleValue:IsA("StringValue") then local role = roleValue.Value:lower() if role:find("killer") then return "Killer" end if role:find("survivor") or role:find("survive") then return "Survivor" end end local isKillerValue = character:FindFirstChild("IsKiller") if isKillerValue and isKillerValue:IsA("BoolValue") and isKillerValue.Value then return "Killer" end local isSurvivorValue = character:FindFirstChild("IsSurvivor") if isSurvivorValue and isSurvivorValue:IsA("BoolValue") and isSurvivorValue.Value then return "Survivor" end if player.Team then local teamName = player.Team.Name:lower() if teamName:find("killer") then return "Killer" end if teamName:find("survivor") or teamName:find("survive") then return "Survivor" end local teamColor = player.TeamColor if teamColor == BrickColor.new("Really red") then return "Killer" end if teamColor == BrickColor.new("Lime green") or teamColor == BrickColor.new("Bright green") then return "Survivor" end end local charName = character.Name:lower() if charName:find("killer") then return "Killer" end if charName:find("survivor") then return "Survivor" end for _, item in pairs(character:GetChildren()) do if item:IsA("Tool") then local toolName = item.Name:lower() if toolName:find("knife") or toolName:find("weapon") or toolName:find("killer") then return "Killer" end end end return "Survivor" end local function GetESPColor(player) local role = GetPlayerRole(player) if role == "Killer" then return Color3.fromRGB(255, 0, 0) elseif role == "Survivor" then return Color3.fromRGB(0, 255, 0) else return Color3.fromRGB(255, 255, 255) end end -- Generator Detection - STRICT version local function IsGenerator(obj) if not obj then return false end if not (obj:IsA("Model") or obj:IsA("BasePart")) then return false end local name = obj.Name:lower() -- EXCLUDE: Player characters, NPCs, tools, GUI elements if name:find("player") or name:find("character") or name:find("npc") or name:find("killer") or name:find("survivor") or name:find("humanoid") then return false end -- Check if it's actually a player character (has Humanoid) if obj:IsA("Model") then if obj:FindFirstChildOfClass("Humanoid") then return false end -- Also check if it's in Players folder for _, p in pairs(Players:GetPlayers()) do if p.Character == obj then return false end end end -- ONLY match specific generator patterns local isGen = false -- Direct generator names if name:find("generator") then isGen = true end if name:find("gen%d") or name:find("gen_%d") or name:find("gen %d") then isGen = true end if name == "gen" then isGen = true end -- Forsaken specific (common patterns) if name:find("fusebox") or name:find("fuse_box") or name:find("fuse box") then isGen = true end if name:find("powerbox") or name:find("power_box") or name:find("power box") then isGen = true end if name:find("switchbox") or name:find("switch_box") then isGen = true end if name:find("lever") and not name:find("player") then isGen = true end return isGen end -- Generator Status Detection local function IsGeneratorCompleted(gen) local genName = gen.Name:lower() -- Check attributes if gen:GetAttribute("Completed") == true then return true end if gen:GetAttribute("IsCompleted") == true then return true end if gen:GetAttribute("Finished") == true then return true end if gen:GetAttribute("Powered") == true then return true end if gen:GetAttribute("Done") == true then return true end -- Progress check local progress = gen:GetAttribute("Progress") if progress and (progress >= 1 or progress >= 100) then return true end -- Check children for completion for _, child in pairs(gen:GetChildren()) do local childName = child.Name:lower() if child:IsA("BoolValue") then if (childName:find("complet") or childName:find("finish") or childName:find("done")) and child.Value then return true end end if child:IsA("NumberValue") or child:IsA("IntValue") then if childName:find("progress") and (child.Value >= 100 or child.Value >= 1) then return true end end end return false end local function GetGeneratorProgress(gen) local progress = gen:GetAttribute("Progress") if progress then if progress <= 1 then return progress * 100 end return progress end for _, child in pairs(gen:GetChildren()) do if child.Name:lower():find("progress") then if child:IsA("NumberValue") or child:IsA("IntValue") then local val = child.Value if val <= 1 then return val * 100 end return val end end end return 0 end -- ESP System local ESPConnections = {} local ESPHighlights = {} local ESPLabels = {} local GenHighlights = {} local GenUpdateConnection = nil local function CreateESPForPlayer(player) if player == LocalPlayer then return end local character = player.Character if not character then return end -- Clean up existing if ESPHighlights[player] then if ESPHighlights[player].Parent then ESPHighlights[player]:Destroy() end end if ESPLabels[player] then if ESPLabels[player].Parent then ESPLabels[player]:Destroy() end end local color = GetESPColor(player) local role = GetPlayerRole(player) local hl = Instance.new("Highlight") hl.Name = "ESP_Player_" .. player.Name hl.FillColor = color hl.OutlineColor = Color3.fromRGB(255, 255, 255) hl.FillTransparency = 0.5 hl.Adornee = character hl.Parent = character ESPHighlights[player] = hl local head = character:FindFirstChild("Head") if head then local billboard = Instance.new("BillboardGui") billboard.Name = "ESP_PlayerLabel_" .. player.Name billboard.Size = UDim2.new(0, 150, 0, 40) billboard.StudsOffset = Vector3.new(0, 3, 0) billboard.Adornee = head billboard.AlwaysOnTop = true billboard.Parent = game.CoreGui local label = Instance.new("TextLabel") label.Size = UDim2.new(1, 0, 1, 0) label.BackgroundTransparency = 1 label.TextColor3 = color label.TextStrokeTransparency = 0 label.TextStrokeColor3 = Color3.fromRGB(0, 0, 0) label.TextScaled = true label.Font = Enum.Font.GothamBold label.Text = player.Name .. " [" .. role .. "]" label.Parent = billboard ESPLabels[player] = billboard end end local function RemoveESPForPlayer(player) if ESPHighlights[player] then if ESPHighlights[player].Parent then ESPHighlights[player]:Destroy() end ESPHighlights[player] = nil end if ESPLabels[player] then if ESPLabels[player].Parent then ESPLabels[player]:Destroy() end ESPLabels[player] = nil end end local function UpdateESPForPlayer(player) if not _G.ESP then return end if player == LocalPlayer then return end local character = player.Character if not character then return end local color = GetESPColor(player) local role = GetPlayerRole(player) if ESPHighlights[player] and ESPHighlights[player].Parent then ESPHighlights[player].FillColor = color ESPHighlights[player].Adornee = character end if ESPLabels[player] and ESPLabels[player].Parent then local label = ESPLabels[player]:FindFirstChild("TextLabel") if label then label.TextColor3 = color label.Text = player.Name .. " [" .. role .. "]" end local head = character:FindFirstChild("Head") if head then ESPLabels[player].Adornee = head end end end -- Generator ESP System local function CreateGeneratorESP(gen) -- Skip if already tracked if GenHighlights[gen] then return end local isCompleted = IsGeneratorCompleted(gen) local progress = GetGeneratorProgress(gen) local fillColor, outlineColor, textColor if isCompleted then fillColor = Color3.fromRGB(0, 255, 100) outlineColor = Color3.fromRGB(150, 255, 150) textColor = Color3.fromRGB(0, 255, 100) else fillColor = Color3.fromRGB(255, 170, 0) outlineColor = Color3.fromRGB(255, 220, 100) textColor = Color3.fromRGB(255, 170, 0) end -- Create highlight local hl = Instance.new("Highlight") hl.Name = "GenESP_Highlight" hl.FillColor = fillColor hl.OutlineColor = outlineColor hl.FillTransparency = 0.5 hl.Adornee = gen hl.Parent = gen -- Create label (only one) local billboard = nil local primaryPart = gen:IsA("Model") and gen.PrimaryPart or (gen:IsA("BasePart") and gen or gen:FindFirstChildWhichIsA("BasePart")) if primaryPart then billboard = Instance.new("BillboardGui") billboard.Name = "GenESP_Label" billboard.Size = UDim2.new(0, 120, 0, 30) billboard.StudsOffset = Vector3.new(0, 5, 0) billboard.Adornee = primaryPart billboard.AlwaysOnTop = true billboard.Parent = game.CoreGui local label = Instance.new("TextLabel") label.Name = "GenLabel" label.Size = UDim2.new(1, 0, 1, 0) label.BackgroundTransparency = 1 label.TextColor3 = textColor label.TextStrokeTransparency = 0 label.TextStrokeColor3 = Color3.fromRGB(0, 0, 0) label.TextScaled = true label.Font = Enum.Font.GothamBold label.Text = isCompleted and "✓ COMPLETE" or ("⚡ " .. math.floor(progress) .. "%") label.Parent = billboard end -- Store reference GenHighlights[gen] = { Highlight = hl, Label = billboard, LastCompleted = isCompleted, LastProgress = progress } end local function UpdateGeneratorESP() if not _G.GenESP then return end for gen, data in pairs(GenHighlights) do if gen and gen.Parent then local isCompleted = IsGeneratorCompleted(gen) local progress = GetGeneratorProgress(gen) -- Update if state changed if isCompleted ~= data.LastCompleted then data.LastCompleted = isCompleted local fillColor, outlineColor, textColor if isCompleted then fillColor = Color3.fromRGB(0, 255, 100) outlineColor = Color3.fromRGB(150, 255, 150) textColor = Color3.fromRGB(0, 255, 100) else fillColor = Color3.fromRGB(255, 170, 0) outlineColor = Color3.fromRGB(255, 220, 100) textColor = Color3.fromRGB(255, 170, 0) end if data.Highlight and data.Highlight.Parent then data.Highlight.FillColor = fillColor data.Highlight.OutlineColor = outlineColor end if data.Label and data.Label.Parent then local label = data.Label:FindFirstChild("GenLabel") if label then label.TextColor3 = textColor label.Text = isCompleted and "✓ COMPLETE" or ("⚡ " .. math.floor(progress) .. "%") end end end -- Update progress if not isCompleted and progress ~= data.LastProgress then data.LastProgress = progress if data.Label and data.Label.Parent then local label = data.Label:FindFirstChild("GenLabel") if label then label.Text = "⚡ " .. math.floor(progress) .. "%" end end end else -- Clean up removed generators if data.Highlight then data.Highlight:Destroy() end if data.Label then data.Label:Destroy() end GenHighlights[gen] = nil end end end local function RemoveAllGeneratorESP() for gen, data in pairs(GenHighlights) do if data.Highlight then data.Highlight:Destroy() end if data.Label then data.Label:Destroy() end end GenHighlights = {} end -- Find all generators local function FindAllGenerators() local generators = {} for _, obj in pairs(Workspace:GetDescendants()) do if IsGenerator(obj) then table.insert(generators, obj) end end return generators end -- Tabs local MainTab = Window:AddTab("Main") local PlayerTab = Window:AddTab("Player") local GameTab = Window:AddTab("Game") local ServerTab = Window:AddTab("Server") local SettingsTab = Window:AddTab("Settings") -- MAIN TAB MainTab:New("Title")({ Title = "🛠️ Quick Actions" }) MainTab:New("Button")({ Title = "Reset Character", Description = "Respawn your character", Callback = function() LocalPlayer:LoadCharacter() Notify("Success", "Character reset!", "Success") end, }) MainTab:New("Button")({ Title = "Refresh Movement", Description = "Reset WalkSpeed, JumpPower & Gravity to defaults", Callback = function() local hum = GetHumanoid() if hum then hum.WalkSpeed = Config.WalkSpeedDefault hum.JumpPower = Config.JumpPowerDefault end Workspace.Gravity = Config.GravityDefault UpdateWalkSpeedUI(Config.WalkSpeedDefault) UpdateJumpPowerUI(Config.JumpPowerDefault) UpdateGravityUI(Config.GravityDefault) Notify("Reset", "Movement & gravity refreshed!", "Success") end, }) MainTab:New("Title")({ Title = "🎯 Teleport" }) local TargetName = "" MainTab:New("Input")({ Title = "Player Name", Description = "Enter target player name", Placeholder = "Type name here...", Callback = function(v) TargetName = v end, }) MainTab:New("Button")({ Title = "Teleport To", Description = "Go to target player", Callback = function() if TargetName == "" then Notify("Warning", "Enter a player name!", "Warning") return end local target = GetPlayerByName(TargetName) if target and target.Character then local myRoot = GetRootPart() local tRoot = target.Character:FindFirstChild("HumanoidRootPart") if myRoot and tRoot then myRoot.CFrame = tRoot.CFrame * CFrame.new(0, 0, 3) Notify("Success", "Teleported to " .. target.Name, "Success") end else Notify("Error", "Player not found!", "Error") end end, }) MainTab:New("Button")({ Title = "Bring Player", Description = "Bring target to you (visual)", Callback = function() if TargetName == "" then Notify("Warning", "Enter a player name!", "Warning") return end local target = GetPlayerByName(TargetName) if target and target.Character then local myRoot = GetRootPart() local tRoot = target.Character:FindFirstChild("HumanoidRootPart") if myRoot and tRoot then tRoot.CFrame = myRoot.CFrame * CFrame.new(0, 0, -3) Notify("Success", "Brought " .. target.Name, "Success") end else Notify("Error", "Player not found!", "Error") end end, }) -- PLAYER TAB PlayerTab:New("Title")({ Title = "🏃 Movement" }) local currentWalkSpeed = Config.WalkSpeedDefault UIElements.WalkSpeedSlider = PlayerTab:New("Slider")({ Title = "WalkSpeed", Description = "Adjust walking speed (Default: 16)", Default = Config.WalkSpeedDefault, Minimum = 1, Maximum = 200, DecimalCount = 0, Callback = function(v) currentWalkSpeed = v local hum = GetHumanoid() if hum then hum.WalkSpeed = v end if UIElements.WalkSpeedInput then pcall(function() UIElements.WalkSpeedInput:Set(tostring(v)) end) end end, }) UIElements.WalkSpeedInput = PlayerTab:New("Input")({ Title = "WalkSpeed (Custom Value)", Description = "Type any value (no limits)", Placeholder = "16", Callback = function(v) local num = tonumber(v) if num then currentWalkSpeed = math.clamp(num, 1, 200) local hum = GetHumanoid() if hum then hum.WalkSpeed = currentWalkSpeed end if UIElements.WalkSpeedSlider then pcall(function() UIElements.WalkSpeedSlider:Set(currentWalkSpeed) end) end end end, }) local currentJumpPower = Config.JumpPowerDefault UIElements.JumpPowerSlider = PlayerTab:New("Slider")({ Title = "Jump Power", Description = "Adjust jump power (Default: 50)", Default = Config.JumpPowerDefault, Minimum = 0, Maximum = 300, DecimalCount = 0, Callback = function(v) currentJumpPower = v local hum = GetHumanoid() if hum then hum.JumpPower = v end if UIElements.JumpPowerInput then pcall(function() UIElements.JumpPowerInput:Set(tostring(v)) end) end end, }) UIElements.JumpPowerInput = PlayerTab:New("Input")({ Title = "Jump Power (Custom Value)", Description = "Type any value (no limits)", Placeholder = "50", Callback = function(v) local num = tonumber(v) if num then currentJumpPower = math.clamp(num, 0, 300) local hum = GetHumanoid() if hum then hum.JumpPower = currentJumpPower end if UIElements.JumpPowerSlider then pcall(function() UIElements.JumpPowerSlider:Set(currentJumpPower) end) end end end, }) local currentGravity = Config.GravityDefault UIElements.GravitySlider = PlayerTab:New("Slider")({ Title = "Gravity", Description = "Adjust workspace gravity (Default: 196)", Default = Config.GravityDefault, Minimum = 0, Maximum = 500, DecimalCount = 0, Callback = function(v) currentGravity = v Workspace.Gravity = v if UIElements.GravityInput then pcall(function() UIElements.GravityInput:Set(tostring(v)) end) end end, }) UIElements.GravityInput = PlayerTab:New("Input")({ Title = "Gravity (Custom Value)", Description = "Type any value (no limits)", Placeholder = "196", Callback = function(v) local num = tonumber(v) if num then currentGravity = math.clamp(num, 0, 500) Workspace.Gravity = currentGravity if UIElements.GravitySlider then pcall(function() UIElements.GravitySlider:Set(currentGravity) end) end end end, }) PlayerTab:New("Title")({ Title = "⚡ Toggles" }) PlayerTab:New("Toggle")({ Title = "Infinite Jump", Description = "Jump in the air", DefaultValue = false, Callback = function(v) if v then _G.InfJump = true _G.InfJumpCon = UserInputService.JumpRequest:Connect(function() if _G.InfJump then local hum = GetHumanoid() if hum then hum:ChangeState(Enum.HumanoidStateType.Jumping) end end end) Notify("Enabled", "Infinite Jump ON", "Success") else _G.InfJump = false if _G.InfJumpCon then _G.InfJumpCon:Disconnect() end Notify("Disabled", "Infinite Jump OFF", "Info") end end, }) PlayerTab:New("Toggle")({ Title = "NoClip", Description = "Walk through walls", DefaultValue = false, Callback = function(v) if v then _G.NC = true _G.NCCon = RunService.Stepped:Connect(function() if _G.NC then local char = LocalPlayer.Character if char then for _, p in pairs(char:GetDescendants()) do if p:IsA("BasePart") then p.CanCollide = false end end end end end) Notify("Enabled", "NoClip ON", "Success") else _G.NC = false if _G.NCCon then _G.NCCon:Disconnect() end Notify("Disabled", "NoClip OFF", "Info") end end, }) PlayerTab:New("Title")({ Title = "✈️ Fly Settings" }) local currentFlySpeed = Config.FlySpeedDefault UIElements.FlySpeedSlider = PlayerTab:New("Slider")({ Title = "Fly Speed", Description = "Set fly movement speed (Default: 100)", Default = Config.FlySpeedDefault, Minimum = 1, Maximum = 500, DecimalCount = 0, Callback = function(v) currentFlySpeed = v Config.FlySpeed = v if UIElements.FlySpeedInput then pcall(function() UIElements.FlySpeedInput:Set(tostring(v)) end) end end, }) UIElements.FlySpeedInput = PlayerTab:New("Input")({ Title = "Fly Speed (Custom Value)", Description = "Type any value (no limits)", Placeholder = "100", Callback = function(v) local num = tonumber(v) if num then currentFlySpeed = math.clamp(num, 1, 500) Config.FlySpeed = currentFlySpeed if UIElements.FlySpeedSlider then pcall(function() UIElements.FlySpeedSlider:Set(currentFlySpeed) end) end end end, }) PlayerTab:New("Button")({ Title = "Reset Fly Speed", Description = "Reset fly speed to default (100)", Callback = function() Config.FlySpeed = Config.FlySpeedDefault currentFlySpeed = Config.FlySpeedDefault UpdateFlySpeedUI(Config.FlySpeedDefault) Notify("Reset", "Fly speed reset to " .. Config.FlySpeedDefault, "Success") end, }) PlayerTab:New("Toggle")({ Title = "Fly [DETECTED AFTER FEW SECONDS OF USE!]", Description = "Toggle client fly", DefaultValue = false, Callback = function(v) if v then _G.Fly = true local root = GetRootPart() if root then local bodyVel = Instance.new("BodyVelocity") bodyVel.Name = "FlyVel" bodyVel.MaxForce = Vector3.new(math.huge, math.huge, math.huge) bodyVel.Velocity = Vector3.new(0, 0, 0) bodyVel.Parent = root local bodyGyro = Instance.new("BodyGyro") bodyGyro.Name = "FlyGyro" bodyGyro.MaxTorque = Vector3.new(math.huge, math.huge, math.huge) bodyGyro.P = 9e4 bodyGyro.Parent = root _G.FlyCon = RunService.RenderStepped:Connect(function() if _G.Fly and root and root.Parent then local cam = Workspace.CurrentCamera local move = Vector3.new(0, 0, 0) local hum = GetHumanoid() if hum and hum.MoveDirection.Magnitude > 0 then move = cam.CFrame:VectorToWorldSpace(Vector3.new(hum.MoveDirection.X, 0, hum.MoveDirection.Z)) end bodyVel.Velocity = move * Config.FlySpeed bodyGyro.CFrame = cam.CFrame end end) Notify("Enabled", "Fly ON (Speed: " .. Config.FlySpeed .. ")", "Success") end else _G.Fly = false if _G.FlyCon then _G.FlyCon:Disconnect() end local root = GetRootPart() if root then local bv = root:FindFirstChild("FlyVel") local bg = root:FindFirstChild("FlyGyro") if bv then bv:Destroy() end if bg then bg:Destroy() end end Notify("Disabled", "Fly OFF", "Info") end end, }) -- GAME TAB GameTab:New("Title")({ Title = "👁️ Visuals" }) GameTab:New("Toggle")({ Title = "ESP Players", Description = "Survivors=Green, Killers=Red, Lobby=White", DefaultValue = false, Callback = function(v) if v then _G.ESP = true for _, p in pairs(Players:GetPlayers()) do if p ~= LocalPlayer then p.CharacterAdded:Connect(function(char) if _G.ESP then task.wait(0.5) CreateESPForPlayer(p) end end) if p.Character then CreateESPForPlayer(p) end end end local playerAddedConn = Players.PlayerAdded:Connect(function(p) p.CharacterAdded:Connect(function() if _G.ESP then task.wait(0.5) CreateESPForPlayer(p) end end) end) table.insert(ESPConnections, playerAddedConn) local updateConn = RunService.Heartbeat:Connect(function() if _G.ESP then for _, p in pairs(Players:GetPlayers()) do if p ~= LocalPlayer and p.Character then UpdateESPForPlayer(p) end end end end) table.insert(ESPConnections, updateConn) Notify("Enabled", "ESP ON - Colors by role!", "Success") else _G.ESP = false for _, conn in pairs(ESPConnections) do if conn then conn:Disconnect() end end ESPConnections = {} for _, p in pairs(Players:GetPlayers()) do RemoveESPForPlayer(p) end Notify("Disabled", "ESP OFF", "Info") end end, }) GameTab:New("Toggle")({ Title = "Fullbright", Description = "Brighter environment", DefaultValue = false, Callback = function(v) if v then _G.OldBright = Lighting.Brightness _G.OldTime = Lighting.ClockTime _G.OldFog = Lighting.FogEnd _G.OldShadows = Lighting.GlobalShadows Lighting.Brightness = 2 Lighting.ClockTime = 14 Lighting.FogEnd = 100000 Lighting.GlobalShadows = false Notify("Enabled", "Fullbright ON", "Success") else Lighting.Brightness = _G.OldBright or 1 Lighting.ClockTime = _G.OldTime or 14 Lighting.FogEnd = _G.OldFog or 100000 Lighting.GlobalShadows = _G.OldShadows or true Notify("Disabled", "Fullbright OFF", "Info") end end, }) GameTab:New("Title")({ Title = "⚡ Generator ESP" }) GameTab:New("Toggle")({ Title = "Generator ESP", Description = "Incomplete=Orange, Complete=Green", DefaultValue = false, Callback = function(v) if v then _G.GenESP = true local generators = FindAllGenerators() local genCount = 0 local completedCount = 0 for _, gen in pairs(generators) do CreateGeneratorESP(gen) genCount = genCount + 1 if IsGeneratorCompleted(gen) then completedCount = completedCount + 1 end end -- Start update loop spawn(function() while _G.GenESP do task.wait(0.5) UpdateGeneratorESP() end end) Notify("Enabled", genCount .. " generators (" .. completedCount .. " done, " .. (genCount - completedCount) .. " left)", "Success") else _G.GenESP = false RemoveAllGeneratorESP() Notify("Disabled", "Generator ESP OFF", "Info") end end, }) GameTab:New("Button")({ Title = "Refresh Generator ESP", Description = "Re-scan for generators", Callback = function() if not _G.GenESP then Notify("Warning", "Enable Generator ESP first!", "Warning") return end local generators = FindAllGenerators() local newCount = 0 for _, gen in pairs(generators) do if not GenHighlights[gen] then CreateGeneratorESP(gen) newCount = newCount + 1 end end Notify("Refreshed", newCount .. " new generators found", "Success") end, }) GameTab:New("Button")({ Title = "Debug: Print All Objects", Description = "Print workspace objects to console (F9)", Callback = function() print("=== FCAL HUB - Workspace Objects ===") local counted = {} for _, obj in pairs(Workspace:GetDescendants()) do if obj:IsA("Model") or obj:IsA("BasePart") then local name = obj.Name if not counted[name] then counted[name] = 0 end counted[name] = counted[name] + 1 end end for name, count in pairs(counted) do print(name .. " (x" .. count .. ")") end Notify("Debug", "Check console (F9) for object list!", "Info") end, }) GameTab:New("Title")({ Title = "🎯 Find Objects" }) GameTab:New("Button")({ Title = "Find Generators", Description = "Highlight generators (Static)", Callback = function() local generators = FindAllGenerators() local c = 0 local completed = 0 for _, gen in pairs(generators) do local isComplete = IsGeneratorCompleted(gen) local hl = Instance.new("Highlight") if isComplete then hl.FillColor = Color3.fromRGB(0, 255, 100) completed = completed + 1 else hl.FillColor = Color3.fromRGB(255, 170, 0) end hl.OutlineColor = Color3.fromRGB(255, 255, 255) hl.FillTransparency = 0.5 hl.Adornee = gen hl.Parent = gen c = c + 1 end Notify("Found", c .. " generators (" .. completed .. " done, " .. (c - completed) .. " left)", "Success") end, }) GameTab:New("Button")({ Title = "Find Exit Gates", Description = "Highlight exit gates", Callback = function() local c = 0 for _, o in pairs(Workspace:GetDescendants()) do if (o.Name:lower():find("gate") or o.Name:lower():find("exit")) and (o:IsA("Model") or o:IsA("BasePart")) then local hl = Instance.new("Highlight") hl.FillColor = Color3.fromRGB(0, 255, 0) hl.OutlineColor = Color3.fromRGB(255, 255, 255) hl.FillTransparency = 0.5 hl.Adornee = o hl.Parent = o c = c + 1 end end Notify("Found", c .. " exit gates highlighted!", "Success") end, }) GameTab:New("Button")({ Title = "Clear Highlights", Description = "Remove all highlights", Callback = function() local count = 0 for _, o in pairs(Workspace:GetDescendants()) do if o:IsA("Highlight") then o:Destroy() count = count + 1 end end -- Also clear from CoreGui for _, o in pairs(game.CoreGui:GetChildren()) do if o.Name:find("ESP_") or o.Name:find("GenESP_") then o:Destroy() end end -- Clear tracking tables ESPHighlights = {} ESPLabels = {} GenHighlights = {} Notify("Cleared", count .. " highlights removed!", "Info") end, }) -- SERVER TAB ServerTab:New("Title")({ Title = "🌐 Server Info" }) ServerTab:New("Button")({ Title = "Copy Job ID", Description = "Copy server JobId", Callback = function() if setclipboard then setclipboard(game.JobId) Notify("Copied", "Job ID copied!", "Success") else Notify("Job ID", game.JobId, "Info") end end, }) ServerTab:New("Button")({ Title = "Copy Place ID", Description = "Copy game PlaceId", Callback = function() if setclipboard then setclipboard(tostring(game.PlaceId)) Notify("Copied", "Place ID copied!", "Success") else Notify("Place ID", tostring(game.PlaceId), "Info") end end, }) ServerTab:New("Title")({ Title = "🚪 Actions" }) ServerTab:New("Button")({ Title = "Rejoin", Description = "Rejoin current server", Callback = function() TeleportService:TeleportToPlaceInstance(game.PlaceId, game.JobId, LocalPlayer) end, }) ServerTab:New("Button")({ Title = "Server Hop", Description = "Join a different server", Callback = function() TeleportService:Teleport(game.PlaceId, LocalPlayer) end, }) ServerTab:New("Title")({ Title = "👁️ Spectate" }) local SpecTarget = "" local names = {} for _, p in pairs(Players:GetPlayers()) do if p ~= LocalPlayer then table.insert(names, p.Name) end end ServerTab:New("Dropdown")({ Title = "Select Player", Description = "Choose player to spectate", Options = #names > 0 and names or {"No Players"}, Default = "", Callback = function(v) SpecTarget = v end, }) ServerTab:New("Button")({ Title = "Spectate", Description = "Watch selected player", Callback = function() if SpecTarget ~= "" then local t = GetPlayerByName(SpecTarget) if t and t.Character then Workspace.CurrentCamera.CameraSubject = t.Character:FindFirstChildOfClass("Humanoid") or t.Character Notify("Spectating", "Now watching " .. t.Name, "Info") end else Notify("Warning", "Select a player first!", "Warning") end end, }) ServerTab:New("Button")({ Title = "Stop Spectating", Description = "Return to your character", Callback = function() if LocalPlayer.Character then Workspace.CurrentCamera.CameraSubject = LocalPlayer.Character:FindFirstChildOfClass("Humanoid") or LocalPlayer.Character Notify("Stopped", "Returned to your view", "Info") end end, }) -- SETTINGS TAB SettingsTab:New("Title")({ Title = "🎨 Theme" }) SettingsTab:New("Dropdown")({ Title = "Select Theme", Description = "Change UI theme", Options = {"Dark", "Light", "Midnight", "Rose", "Emerald"}, Default = Config.Theme, Callback = function(v) Window:SetTheme(v) Notify("Theme", "Changed to " .. v, "Success") end, }) SettingsTab:New("Title")({ Title = "⌨️ Keybind" }) local ToggleKey = "RightControl" SettingsTab:New("Keybind")({ Title = "Toggle UI", Description = "Key to hide/show", DefaultKeybind = ToggleKey, Callback = function(k) ToggleKey = k end, }) SettingsTab:New("Title")({ Title = "❌ Exit" }) SettingsTab:New("Button")({ Title = "Destroy UI", Description = "Close FCAL HUB", Callback = function() _G.InfJump = false; if _G.InfJumpCon then _G.InfJumpCon:Disconnect() end _G.NC = false; if _G.NCCon then _G.NCCon:Disconnect() end _G.Fly = false; if _G.FlyCon then _G.FlyCon:Disconnect() end _G.ESP = false; _G.GenESP = false for _, conn in pairs(ESPConnections) do if conn then conn:Disconnect() end end for _, p in pairs(Players:GetPlayers()) do RemoveESPForPlayer(p) end RemoveAllGeneratorESP() Window:Destroy() end, }) -- Keybind Handler UserInputService.InputBegan:Connect(function(input, processed) if processed then return end if Modal:IsCorrectInput(input, ToggleKey) then local gui = LocalPlayer:FindFirstChild("PlayerGui") if gui then local m = gui:FindFirstChild("Modal") if m then m.Enabled = not m.Enabled end end end end) -- Init Notify("FCAL HUB", "Loaded successfully! v1.0.6", "Success") print("FCAL HUB v1.0.6 - Loaded!")