-- [[ Rscripts Risk Notice ]] -- This script is not verified by rscripts.net. Deal with caution. -- -- Stay safe: -- • Never log in on unofficial Roblox sites or lookalike domains. -- • Real Roblox links use roblox.com (check the .com ending). -- • Treat fake Roblox login / "claim reward" pages as phishing. -- [[ End Rscripts Risk Notice ]] local playersService = game:GetService("Players") local runService = game:GetService("RunService") local userInputService = game:GetService("UserInputService") local replicatedStorage = game:GetService("ReplicatedStorage") local httpService = game:GetService("HttpService") local STATE = STATE if not STATE then STATE = { connect = function(signal, fn) return signal:Connect(fn) end, onCleanup = function() end, } end local VALID_KEYS = { E = true, R = true, T = true, F = true, G = true } local MENU_TOGGLE_KEY = Enum.KeyCode.RightShift local AUTO_START_COOLDOWN = 1 local FREE_CAM_SENSITIVITY = 0.0035 local FREE_CAM_ZOOM_SENSITIVITY = 1.5 local FREE_CAM_MIN_DISTANCE = 4 local FREE_CAM_MAX_DISTANCE = 30 local FREE_CAM_PITCH_LIMIT = math.rad(80) local FREE_CAM_RENDER_PRIORITY = Enum.RenderPriority.First.Value local CONFIG_FOLDER = "Potent" local CONFIG_PATH = "Potent/qte_config.json" local QTE_TYPES = { "XSAW", "TOMAHAWK", "MACHETE", "MACHETEPARRY", "CHOKE", "WINCHESTER", "WINCHESTERBLOCK" } local QTE_TYPE_LABELS = { XSAW = "XSAW", TOMAHAWK = "TOMAHAWK", MACHETE = "U. MACHETE PARRY", MACHETEPARRY = "U. MACHETE BLOCK", CHOKE = "CHOKE", WINCHESTER = "WINCHESTER", WINCHESTERBLOCK = "WINCHESTER BLOCK", } local localPlayer = playersService.LocalPlayer local playerGui = localPlayer:WaitForChild("PlayerGui") local localScriptRoot = playerGui:WaitForChild("LocalScript") local qteRoot = playerGui:WaitForChild("QTE") local qteKey = qteRoot.key local qteLetter = qteKey.ScanPanel.Letter local qteValue = replicatedStorage:WaitForChild("qte") local Potent = { autoQteEnabled = false, highlighterEnabled = true, autoSelectEnabled = false, selectedQteType = "XSAW", tapInterval = 0.05, lastTapAt = 0, lastAutoStartAt = 0, freeCamEnabled = false, } local freeCamActive = false local orbitYaw = 0 local orbitPitch = 0 local orbitDistance = 10 local preFreeCamCFrame = nil local screenGui = nil local statusLabel = nil local autoQteToggleButton = nil local highlighterToggleButton = nil local autoSelectToggleButton = nil local typeCycleButton = nil local tapIntervalLabel = nil local freeCamToggleButton = nil local fluent = nil local fluentWindow = nil local fluentOptions = nil local keyHighlighter = nil local function getThirdPersonFocus() if localScriptRoot.pov.Value ~= "THIRDPERSON" then return nil end local ragdollRig = workspace:FindFirstChild("ragdoll_rig") if ragdollRig then return ragdollRig.Head.Position end local rig = workspace:FindFirstChild("Rig") local chain = workspace:FindFirstChild("chain") if rig and chain then return (rig.Head.Position + chain.Head.Position) / 2 end return nil end local function beginFreeCam(focusPosition) local camPart = workspace:FindFirstChild("campart") if not camPart then return end if not freeCamActive and not preFreeCamCFrame then preFreeCamCFrame = camPart.CFrame end local offset = camPart.Position - focusPosition orbitDistance = math.clamp(offset.Magnitude, FREE_CAM_MIN_DISTANCE, FREE_CAM_MAX_DISTANCE) if offset.Magnitude > 0.01 then local direction = offset.Unit orbitPitch = math.asin(math.clamp(direction.Y, -1, 1)) orbitYaw = math.atan2(direction.X, direction.Z) end freeCamActive = true userInputService.MouseBehavior = Enum.MouseBehavior.LockCenter end local function endFreeCam() freeCamActive = false userInputService.MouseBehavior = Enum.MouseBehavior.Default end local function onFreeCamRenderStep() local camPart = workspace:FindFirstChild("campart") if not camPart then return end if Potent.freeCamEnabled then local focusPosition = getThirdPersonFocus() if not focusPosition then return end local direction = Vector3.new( math.cos(orbitPitch) * math.sin(orbitYaw), math.sin(orbitPitch), math.cos(orbitPitch) * math.cos(orbitYaw) ) camPart.CFrame = CFrame.new(focusPosition + direction * orbitDistance) end end local function saveConfig() if not isfolder(CONFIG_FOLDER) then makefolder(CONFIG_FOLDER) end local data = { autoQteEnabled = Potent.autoQteEnabled, highlighterEnabled = Potent.highlighterEnabled, autoSelectEnabled = Potent.autoSelectEnabled, selectedQteType = Potent.selectedQteType, tapInterval = Potent.tapInterval, freeCamEnabled = Potent.freeCamEnabled, } writefile(CONFIG_PATH, httpService:JSONEncode(data)) end local function loadConfig() if not isfile(CONFIG_PATH) then return end local ok, data = pcall(function() return httpService:JSONDecode(readfile(CONFIG_PATH)) end) if not ok or type(data) ~= "table" then return end if type(data.autoQteEnabled) == "boolean" then Potent.autoQteEnabled = data.autoQteEnabled end if type(data.highlighterEnabled) == "boolean" then Potent.highlighterEnabled = data.highlighterEnabled end if type(data.autoSelectEnabled) == "boolean" then Potent.autoSelectEnabled = data.autoSelectEnabled end if type(data.selectedQteType) == "string" and QTE_TYPE_LABELS[data.selectedQteType] then Potent.selectedQteType = data.selectedQteType end if type(data.tapInterval) == "number" then Potent.tapInterval = data.tapInterval end if type(data.freeCamEnabled) == "boolean" then Potent.freeCamEnabled = data.freeCamEnabled end end local function setAutoQteState(enabled) Potent.autoQteEnabled = enabled end local function setHighlighterState(enabled) Potent.highlighterEnabled = enabled end local function setAutoSelectState(enabled) Potent.autoSelectEnabled = enabled end local function setFreeCamState(enabled) Potent.freeCamEnabled = enabled if not enabled then endFreeCam() end end local function tryAutoStart() if not Potent.autoSelectEnabled or qteValue.Value then return end local now = os.clock() if now - Potent.lastAutoStartAt < AUTO_START_COOLDOWN then return end Potent.lastAutoStartAt = now localScriptRoot.lastselected.Value = Potent.selectedQteType replicatedStorage.StartQTE:FireServer(Potent.selectedQteType) end local function cycleQteType() local index = table.find(QTE_TYPES, Potent.selectedQteType) or 1 index = index % #QTE_TYPES + 1 Potent.selectedQteType = QTE_TYPES[index] end local function adjustTapInterval(delta) Potent.tapInterval = math.clamp(Potent.tapInterval + delta, 0.02, 0.2) end local function buildQtePage(tab) tab:AddParagraph({ Title = "Chain Practice / QTE Control (Updated as of September 23. 2026.)", Content = "Fast input assistance for the current prompt. The floating key marker appears above the fight when enabled." }) autoQteToggleButton = tab:AddToggle("AutoQTE", { Title = "Auto QTE", Description = "Press the displayed QTE key while Roblox is focused.", Default = Potent.autoQteEnabled, Callback = setAutoQteState }) highlighterToggleButton = tab:AddToggle("KeyHighlighter", { Title = "Key highlighter (uterly useless)", Description = "Show the current prompt as a large on-screen key.", Default = Potent.highlighterEnabled, Callback = setHighlighterState }) autoSelectToggleButton = tab:AddToggle("AutoSelect", { Title = "Auto-select QTE", Description = "Automatically start the selected practice type when available.", Default = Potent.autoSelectEnabled, Callback = function(value) setAutoSelectState(value) tryAutoStart() end }) local qteLabels = {} for _, qteType in ipairs(QTE_TYPES) do table.insert(qteLabels, QTE_TYPE_LABELS[qteType]) end typeCycleButton = tab:AddDropdown("QTEType", { Title = "Practice type", Description = "Choose the QTE sequence used by auto-select.", Values = qteLabels, Default = QTE_TYPE_LABELS[Potent.selectedQteType], Callback = function(value) for qteType, label in pairs(QTE_TYPE_LABELS) do if label == value then Potent.selectedQteType = qteType break end end end }) tab:AddParagraph({ Title = "Menu hotkey", Content = "Right Shift toggles the Fluent window. Use the minimize control for a quick hide." }) end local function buildSettingsPage(tab) tab:AddParagraph({ Title = "Input tuning", Content = "Lower intervals are faster but may be less reliable if the game or executor is under load." }) tapIntervalLabel = tab:AddSlider("TapInterval", { Title = "Tap interval", Description = "Delay between repeated prompt taps.", Min = 0.02, Max = 0.2, Default = Potent.tapInterval, Rounding = 2, Callback = function(value) Potent.tapInterval = value end }) tab:AddButton({Title = "Save configuration", Description = "Write the current Potent settings to disk.", Callback = saveConfig}) tab:AddButton({ Title = "Load configuration", Description = "Read the saved Potent settings and apply them.", Callback = function() loadConfig() if fluentOptions then pcall(function() fluentOptions.AutoQTE:SetValue(Potent.autoQteEnabled) end) pcall(function() fluentOptions.KeyHighlighter:SetValue(Potent.highlighterEnabled) end) pcall(function() fluentOptions.AutoSelect:SetValue(Potent.autoSelectEnabled) end) pcall(function() fluentOptions.QTEType:SetValue(QTE_TYPE_LABELS[Potent.selectedQteType]) end) pcall(function() fluentOptions.TapInterval:SetValue(Potent.tapInterval) end) end end }) end local function buildCameraPage(tab) tab:AddParagraph({ Title = "Third-person orbit", Content = "Enable this, then hold RMB in third person. Move the mouse to orbit and use the wheel to zoom." }) freeCamToggleButton = tab:AddToggle("FreeCamera", { Title = "Free camera", Description = "Uses the game's camera anchor and eases back after RMB is released.", Default = Potent.freeCamEnabled, Callback = setFreeCamState }) end local function buildUi() local existingPotentUi = gethui():FindFirstChild("PotentUI") if existingPotentUi then existingPotentUi:Destroy() end local existingFluentUi = gethui():FindFirstChild("ScreenGui") if existingFluentUi then existingFluentUi:Destroy() end fluent = loadstring(game:HttpGet("https://github.com/dawid-scripts/Fluent/releases/latest/download/main.lua"))() fluentWindow = fluent:CreateWindow({ Title = "Potent / Chain Practice", SubTitle = "Auto QTE control", TabWidth = 150, Size = UDim2.fromOffset(620, 500), Acrylic = true, Theme = "Dark", MinimizeKey = MENU_TOGGLE_KEY, }) local tabs = { QTE = fluentWindow:AddTab({Title = "QTE", Icon = "zap"}), Camera = fluentWindow:AddTab({Title = "Camera", Icon = "camera"}), Settings = fluentWindow:AddTab({Title = "Settings", Icon = "settings"}), } fluentOptions = fluent.Options buildQtePage(tabs.QTE) buildCameraPage(tabs.Camera) buildSettingsPage(tabs.Settings) fluentWindow:SelectTab(1) screenGui = fluent.GUI fluent:Notify({ Title = "Potent loaded", Content = "Fluent interface ready. Right Shift toggles the menu.", Duration = 4, }) STATE.onCleanup(function() if fluent then pcall(function() fluent:Destroy() end) end end) end local function buildKeyHighlighter() keyHighlighter = Drawing.new("Text") keyHighlighter.Visible = false keyHighlighter.Center = true keyHighlighter.Outline = true keyHighlighter.Font = Drawing.Fonts.Plex keyHighlighter.Size = 64 keyHighlighter.Color = Color3.fromRGB(255, 255, 255) STATE.onCleanup(function() keyHighlighter:Remove() end) end local function onHeartbeat() tryAutoStart() if not qteKey.Visible then if statusLabel then statusLabel.Text = "Status: Idle" end keyHighlighter.Visible = false return end local letter = qteLetter.Text if not VALID_KEYS[letter] then keyHighlighter.Visible = false return end if Potent.highlighterEnabled then local camera = workspace.CurrentCamera keyHighlighter.Position = Vector2.new(camera.ViewportSize.X / 2, camera.ViewportSize.Y * 0.35) keyHighlighter.Text = letter keyHighlighter.Visible = true else keyHighlighter.Visible = false end if not Potent.autoQteEnabled or not isrbxactive() then if statusLabel then statusLabel.Text = "Status: Idle" end return end if statusLabel then statusLabel.Text = "Status: Pressing " .. letter end local now = os.clock() if now - Potent.lastTapAt < Potent.tapInterval then return end Potent.lastTapAt = now keytap(string.byte(letter)) end local function onInitError(err) warn("Potent Auto QTE failed to initialize.") warn(err) warn(debug.traceback()) end local function initializeScript() loadConfig() buildUi() buildKeyHighlighter() STATE.connect(userInputService.InputBegan, function(input, processed) if processed then return end if input.KeyCode == MENU_TOGGLE_KEY then screenGui.Enabled = not screenGui.Enabled return end if input.UserInputType == Enum.UserInputType.MouseButton2 and Potent.freeCamEnabled then local focusPosition = getThirdPersonFocus() if focusPosition then beginFreeCam(focusPosition) end end end) STATE.connect(userInputService.InputEnded, function(input) if input.UserInputType == Enum.UserInputType.MouseButton2 then endFreeCam() end end) STATE.connect(userInputService.InputChanged, function(input) if not freeCamActive then return end if input.UserInputType == Enum.UserInputType.MouseMovement then orbitYaw = orbitYaw - input.Delta.X * FREE_CAM_SENSITIVITY orbitPitch = math.clamp(orbitPitch - input.Delta.Y * FREE_CAM_SENSITIVITY, -FREE_CAM_PITCH_LIMIT, FREE_CAM_PITCH_LIMIT) elseif input.UserInputType == Enum.UserInputType.MouseWheel then orbitDistance = math.clamp(orbitDistance - input.Position.Z * FREE_CAM_ZOOM_SENSITIVITY, FREE_CAM_MIN_DISTANCE, FREE_CAM_MAX_DISTANCE) end end) pcall(function() runService:UnbindFromRenderStep("PotentFreeCam") end) runService:BindToRenderStep("PotentFreeCam", FREE_CAM_RENDER_PRIORITY, onFreeCamRenderStep) STATE.onCleanup(function() runService:UnbindFromRenderStep("PotentFreeCam") userInputService.MouseBehavior = Enum.MouseBehavior.Default local camPart = workspace:FindFirstChild("campart") if camPart and preFreeCamCFrame then camPart.CFrame = preFreeCamCFrame end end) STATE.connect(runService.Heartbeat, onHeartbeat) end xpcall(initializeScript, onInitError)