-- draw with the ball local Players = game:GetService("Players") local UserInputService = game:GetService("UserInputService") local ReplicatedStorage = game:GetService("ReplicatedStorage") local RunService = game:GetService("RunService") local player = Players.LocalPlayer local mouse = player:GetMouse() local camera = workspace.CurrentCamera -- Configuration local config = { ballSize = 2, drawInterval = 0.05 } -- State local state = { mode = "empty", -- "empty", "select", "draw" selectedCanvas = nil, drawing = false, lastDrawTime = 0, drawnPositions = {}, pointerDot = nil, connections = {} } -- Create Pointer Dot local function createPointerDot() local dot = Instance.new("Part") dot.Name = "PointerDot" dot.Size = Vector3.new(0.5, 0.5, 0.5) dot.Shape = Enum.PartType.Ball dot.Anchored = true dot.CanCollide = false dot.Material = Enum.Material.Neon dot.Color = Color3.fromRGB(255, 255, 0) dot.Transparency = 0.3 dot.Parent = workspace return dot end state.pointerDot = createPointerDot() state.pointerDot.Parent = nil -- Hide initially -- Create GUI local screenGui = Instance.new("ScreenGui") screenGui.Name = "DrawingToolGui" screenGui.ResetOnSpawn = false screenGui.Parent = player:WaitForChild("PlayerGui") -- Adjusted size and position for compactness local mainFrame = Instance.new("Frame") mainFrame.Name = "MainFrame" mainFrame.Size = UDim2.new(0, 200, 0, 300) -- Reduced overall size mainFrame.Position = UDim2.new(1, -210, 0, 10) -- Moved to top right corner mainFrame.BackgroundColor3 = Color3.fromRGB(40, 40, 40) mainFrame.BorderSizePixel = 2 mainFrame.BorderColor3 = Color3.fromRGB(100, 100, 100) mainFrame.Parent = screenGui mainFrame.Active = true mainFrame.Draggable = true -- UIListLayout for vertical compact stacking local listLayout = Instance.new("UIListLayout") listLayout.Padding = UDim.new(0, 5) listLayout.HorizontalAlignment = Enum.HorizontalAlignment.Center listLayout.SortOrder = Enum.SortOrder.LayoutOrder listLayout.Parent = mainFrame -- Title/Header Frame to hold Title and Close button (not affected by list layout) local headerFrame = Instance.new("Frame") headerFrame.Name = "HeaderFrame" headerFrame.Size = UDim2.new(1, 0, 0, 25) headerFrame.BackgroundTransparency = 1 headerFrame.Parent = mainFrame headerFrame.LayoutOrder = 1 -- First item in the list -- Title local title = Instance.new("TextLabel") title.Size = UDim2.new(1, -25, 1, 0) title.Position = UDim2.new(0, 0, 0, 0) title.BackgroundColor3 = Color3.fromRGB(30, 30, 30) title.BorderSizePixel = 0 title.Text = "Ball Drawing Tool" title.TextColor3 = Color3.fromRGB(255, 255, 255) title.TextSize = 14 -- Reduced size title.Font = Enum.Font.SourceSansBold title.Parent = headerFrame -- Close Button local closeBtn = Instance.new("TextButton") closeBtn.Name = "CloseButton" closeBtn.Size = UDim2.new(0, 25, 1, 0) -- Reduced size closeBtn.Position = UDim2.new(1, -25, 0, 0) closeBtn.BackgroundColor3 = Color3.fromRGB(180, 50, 50) closeBtn.BorderSizePixel = 0 closeBtn.Text = "X" closeBtn.TextColor3 = Color3.fromRGB(255, 255, 255) closeBtn.TextSize = 14 -- Reduced size closeBtn.Font = Enum.Font.SourceSansBold closeBtn.Parent = headerFrame -- Mode Label local modeLabel = Instance.new("TextLabel") modeLabel.Size = UDim2.new(1, -10, 0, 25) -- Reduced size and padding modeLabel.Position = UDim2.new(0, 5, 0, 30) -- Position is handled by UIListLayout modeLabel.BackgroundColor3 = Color3.fromRGB(80, 80, 80) modeLabel.BorderSizePixel = 1 modeLabel.Text = "MODE: EMPTY" modeLabel.TextColor3 = Color3.fromRGB(255, 255, 255) modeLabel.TextSize = 12 modeLabel.Font = Enum.Font.SourceSansBold modeLabel.Parent = mainFrame modeLabel.LayoutOrder = 2 -- Canvas Info (Single line, less verbose) local canvasInfo = Instance.new("TextLabel") canvasInfo.Size = UDim2.new(1, -10, 0, 20) -- Reduced size canvasInfo.Position = UDim2.new(0, 5, 0, 60) -- Position is handled by UIListLayout canvasInfo.BackgroundColor3 = Color3.fromRGB(50, 50, 50) canvasInfo.BorderSizePixel = 1 canvasInfo.Text = "No canvas selected" canvasInfo.TextColor3 = Color3.fromRGB(200, 200, 200) canvasInfo.TextSize = 11 canvasInfo.Font = Enum.Font.SourceSans canvasInfo.TextXAlignment = Enum.TextXAlignment.Left -- Left align to fit more text canvasInfo.TextWrapped = true canvasInfo.TextScaled = false -- Keep text size fixed canvasInfo.Parent = mainFrame canvasInfo.LayoutOrder = 3 -- Settings Frame (Made smaller and more horizontal) local settingsFrame = Instance.new("Frame") settingsFrame.Name = "SettingsFrame" settingsFrame.Size = UDim2.new(1, -10, 0, 50) -- Reduced size, enough for title and 2 rows settingsFrame.Position = UDim2.new(0, 5, 0, 90) -- Position is handled by UIListLayout settingsFrame.BackgroundColor3 = Color3.fromRGB(50, 50, 50) settingsFrame.BorderSizePixel = 1 settingsFrame.Parent = mainFrame settingsFrame.LayoutOrder = 4 local settingsTitle = Instance.new("TextLabel") settingsTitle.Size = UDim2.new(1, 0, 0, 15) settingsTitle.BackgroundTransparency = 1 settingsTitle.Text = "Settings" settingsTitle.TextColor3 = Color3.fromRGB(255, 255, 255) settingsTitle.TextSize = 12 settingsTitle.Font = Enum.Font.SourceSansBold settingsTitle.Parent = settingsFrame local settingsContainer = Instance.new("Frame") settingsContainer.Size = UDim2.new(1, 0, 1, -15) -- Occupy space below title settingsContainer.Position = UDim2.new(0, 0, 0, 15) settingsContainer.BackgroundTransparency = 1 settingsContainer.Parent = settingsFrame local settingsGridLayout = Instance.new("UIGridLayout") settingsGridLayout.CellSize = UDim2.new(0.5, -5, 1, 0) -- Two columns settingsGridLayout.CellPadding = UDim2.new(0, 5, 0, 0) settingsGridLayout.HorizontalAlignment = Enum.HorizontalAlignment.Center settingsGridLayout.Parent = settingsContainer local function createSetting(name, labelText, defaultValue, callback) local frame = Instance.new("Frame") frame.BackgroundTransparency = 1 frame.Size = UDim2.new(0, 0, 0, 25) -- Size handled by UIGridLayout frame.Parent = settingsContainer local label = Instance.new("TextLabel") label.Size = UDim2.new(0.5, 0, 1, 0) label.Position = UDim2.new(0, 0, 0, 0) label.BackgroundTransparency = 1 label.Text = labelText label.TextColor3 = Color3.fromRGB(200, 200, 200) label.TextSize = 11 label.Font = Enum.Font.SourceSans label.TextXAlignment = Enum.TextXAlignment.Left label.Parent = frame local input = Instance.new("TextBox") input.Name = name input.Size = UDim2.new(0.5, 0, 1, 0) input.Position = UDim2.new(0.5, 0, 0, 0) input.BackgroundColor3 = Color3.fromRGB(70, 70, 70) input.BorderSizePixel = 1 input.Text = tostring(defaultValue) input.TextColor3 = Color3.fromRGB(255, 255, 255) input.TextSize = 11 input.Font = Enum.Font.SourceSans input.Parent = frame input.FocusLost:Connect(function() callback(input) end) return input end createSetting("BallSize", "Size:", config.ballSize, function(input) local num = tonumber(input.Text) if num and num > 0 and num <= 50 then config.ballSize = num else input.Text = tostring(config.ballSize) end end) createSetting("DrawInterval", "Speed:", config.drawInterval, function(input) local num = tonumber(input.Text) if num and num >= 0.01 and num <= 1 then config.drawInterval = num else input.Text = tostring(config.drawInterval) end end) -- Mode Buttons local buttonsFrame = Instance.new("Frame") buttonsFrame.Size = UDim2.new(1, -10, 0, 120) -- Reduced size buttonsFrame.Position = UDim2.new(0, 5, 0, 175) -- Position is handled by UIListLayout buttonsFrame.BackgroundTransparency = 1 buttonsFrame.Parent = mainFrame buttonsFrame.LayoutOrder = 5 local buttonsListLayout = Instance.new("UIListLayout") buttonsListLayout.Padding = UDim.new(0, 5) buttonsListLayout.HorizontalAlignment = Enum.HorizontalAlignment.Center buttonsListLayout.SortOrder = Enum.SortOrder.LayoutOrder buttonsListLayout.Parent = buttonsFrame local function createButton(name, text, color, callback) local btn = Instance.new("TextButton") btn.Name = name btn.Size = UDim2.new(1, 0, 0, 25) -- Reduced size btn.BackgroundColor3 = color btn.BorderSizePixel = 1 btn.BorderColor3 = Color3.fromRGB(100, 100, 100) btn.Text = text btn.TextColor3 = Color3.fromRGB(255, 255, 255) btn.TextSize = 12 btn.Font = Enum.Font.SourceSansBold btn.Parent = buttonsFrame btn.MouseButton1Click:Connect(callback) return btn end local emptyBtn, selectBtn, drawBtn, f3xBtn emptyBtn = createButton("EmptyMode", "EMPTY MODE", Color3.fromRGB(80, 80, 80), function() state.mode = "empty" modeLabel.Text = "MODE: EMPTY" modeLabel.BackgroundColor3 = Color3.fromRGB(80, 80, 80) state.pointerDot.Parent = nil emptyBtn.BorderSizePixel = 3 selectBtn.BorderSizePixel = 1 drawBtn.BorderSizePixel = 1 if f3xBtn then f3xBtn.BorderSizePixel = 1 end end) emptyBtn.BorderSizePixel = 3 selectBtn = createButton("SelectMode", "SELECT CANVAS", Color3.fromRGB(200, 150, 50), function() state.mode = "select" modeLabel.Text = "MODE: SELECT CANVAS" modeLabel.BackgroundColor3 = Color3.fromRGB(200, 150, 50) canvasInfo.Text = "Click any part to select" state.pointerDot.Parent = nil emptyBtn.BorderSizePixel = 1 selectBtn.BorderSizePixel = 3 drawBtn.BorderSizePixel = 1 if f3xBtn then f3xBtn.BorderSizePixel = 1 end end) drawBtn = createButton("DrawMode", "DRAW MODE", Color3.fromRGB(60, 120, 60), function() if not state.selectedCanvas then canvasInfo.Text = "Select a canvas first!" return end state.mode = "draw" modeLabel.Text = "MODE: DRAW" modeLabel.BackgroundColor3 = Color3.fromRGB(60, 120, 60) state.pointerDot.Parent = workspace emptyBtn.BorderSizePixel = 1 selectBtn.BorderSizePixel = 1 drawBtn.BorderSizePixel = 3 if f3xBtn then f3xBtn.BorderSizePixel = 1 end end) -- New F3X Button f3xBtn = createButton("GetF3X", "GET F3X", Color3.fromRGB(50, 100, 180), function() print("Attempting to load F3X...") -- Execute the provided loadstring loadstring(game:HttpGet("https://raw.githubusercontent.com/infyiff/backup/refs/heads/main/f3x.lua"))() -- Reset border for other mode buttons emptyBtn.BorderSizePixel = 1 selectBtn.BorderSizePixel = 1 drawBtn.BorderSizePixel = 1 f3xBtn.BorderSizePixel = 3 -- Highlight F3X button -- Visually indicate the button was pressed modeLabel.Text = "F3X Loaded (Check Console)" modeLabel.BackgroundColor3 = Color3.fromRGB(50, 100, 180) state.mode = "empty" -- Set mode to empty to clear drawing state state.pointerDot.Parent = nil end) -- Helper Functions local function positionKey(pos) return math.floor(pos.X * 100) .. "," .. math.floor(pos.Y * 100) .. "," .. math.floor(pos.Z * 100) end local function createBallAtPosition(cframe) local pos = cframe.Position local key = positionKey(pos) if state.drawnPositions[key] then return end local size = config.ballSize local args = { cframe, Vector3.new(size, size, size), "Balls" } local success, err = pcall(function() ReplicatedStorage:WaitForChild("Remotes"):WaitForChild("ReplicateJumps"):InvokeServer(unpack(args)) end) if success then state.drawnPositions[key] = true else warn("Failed to create ball:", err) end end local function getCanvasHitPosition() if not state.selectedCanvas or not state.selectedCanvas.Parent then state.selectedCanvas = nil canvasInfo.Text = "Canvas was deleted!" state.mode = "empty" modeLabel.Text = "MODE: EMPTY" modeLabel.BackgroundColor3 = Color3.fromRGB(80, 80, 80) state.pointerDot.Parent = nil return nil end local targetPart = state.selectedCanvas local mouseRay = camera:ScreenPointToRay(mouse.X, mouse.Y) local rayOrigin = mouseRay.Origin local rayDirection = mouseRay.Direction * 1000 local raycastParams = RaycastParams.new() raycastParams.FilterType = Enum.RaycastFilterType.Include raycastParams.FilterDescendantsInstances = {targetPart} local result = workspace:Raycast(rayOrigin, rayDirection, raycastParams) if result and result.Instance == targetPart then local hitPos = result.Position local normal = result.Normal local cframe = CFrame.new(hitPos, hitPos + normal) return cframe end return nil end -- Cleanup function local function cleanup() -- Disconnect all connections for _, conn in pairs(state.connections) do if conn then conn:Disconnect() end end -- Remove pointer dot if state.pointerDot then state.pointerDot:Destroy() end -- Remove GUI if screenGui then screenGui:Destroy() end print("Ball Drawing Tool closed and cleaned up") end -- Close Button closeBtn.MouseButton1Click:Connect(cleanup) -- Input Handling state.connections.mouseDown = mouse.Button1Down:Connect(function() if state.mode == "select" then local target = mouse.Target if target and target:IsA("BasePart") then state.selectedCanvas = target canvasInfo.Text = "Canvas: " .. target.Name local originalColor = target.Color local originalTransparency = target.Transparency target.Color = Color3.fromRGB(255, 255, 0) target.Transparency = math.max(0, target.Transparency - 0.3) wait(0.3) if target.Parent then target.Color = originalColor target.Transparency = originalTransparency end end elseif state.mode == "draw" then state.drawing = true local cframe = getCanvasHitPosition() if cframe then createBallAtPosition(cframe) state.lastDrawTime = tick() end end end) state.connections.mouseUp = mouse.Button1Up:Connect(function() state.drawing = false end) -- Main Loop state.connections.renderStep = RunService.RenderStepped:Connect(function() if state.mode == "draw" and state.selectedCanvas then local cframe = getCanvasHitPosition() if cframe then state.pointerDot.CFrame = cframe if state.drawing then local currentTime = tick() if currentTime - state.lastDrawTime >= config.drawInterval then createBallAtPosition(cframe) state.lastDrawTime = currentTime end end end end end) print("Ball Drawing Tool loaded!")