Browse
Script Types
Tools
Community
Reach players with keyless, universal, or place-specific scripts.


This Ultimate Gym Game script was created by the BobloScript.com team to automate training without getting stuck on busy machines or low stamina. Auto Train handles supported exercises, Auto Rep keeps sets moving, and Force Hypertrophy Weight targets the game’s muscle-growth rep range. Auto Food Manager, cleaning tools, and automatic rest help keep longer training sessions running.
Auto Train moves through supported gym equipment and performs the training cycle automatically.
The script supports machines and stations such as:
Pec Fly
Seated Leg Curl
Pull / Dip Bar
Abs Crunch
Adjustable Seat
Yoga Mat
Multi Cable
Squat Rack
Bench
Skip Busy Machines helps prevent the routine from stopping when another player is already using a selected machine.
Force Hypertrophy Weight attempts to choose a weight that keeps the current exercise in the Hypertrophy range.
Current game information identifies 4–8 reps as the Hypertrophy range, focused on muscle-mass progression.
You can also use Apply Hypertrophy Weight Now when you want the script to adjust the current exercise immediately rather than waiting for the next automated cycle.
Leave Machine to Rest Stamina makes the character stop exercising when recovery is needed instead of continuously forcing reps.
Once the script is ready to continue, Auto Train can return to the workout. This creates a more controlled cycle than simply spamming repetitions until the character can no longer train.
Food is part of Ultimate Gym Game’s normal training economy: players earn Cash and can buy food and supplements to support their sessions.
The script includes:
Minimum Calories
Auto Food Manager
Auto Buy Only
Buy Chicken Once
Eat Chicken Once
These settings let you decide when the script should buy or consume food instead of spending Cash continuously.
Auto Clean and Auto Clean Trash automate supported cleaning jobs around the gym.
Clean Once All can be used when you want the available cleaning tasks processed once instead of keeping a permanent cleaning loop active.
Cleaning floor trash and spills is also part of the game’s secondary cash-making activities.
Yes. BobloScript includes separate timing controls:
Train Delay
Rep Delay
Clean Delay
Eat Delay
Buy Delay
Increase a delay if an action starts failing or being skipped. Very low delays are not automatically better.
Yes. It was created by the BobloScript.com team.
The script is open source and no key, so there is no external key-system step before execution.
Open Ultimate Gym Game and wait for your character to load.
Copy the BobloScript.com code.
Open a compatible Roblox executor.
Paste the code and press Execute.
Select the exercises you want Auto Train to use.
Enable Skip Busy Machines for crowded servers.
Configure stamina and food settings.
Use Force Hypertrophy Weight when training for muscle-growth progression.
Adjust Train and Rep Delay if the automation moves too quickly.
Use Leave Exercise or Unload when you want to stop the current routine.
The game’s developer notes that Ultimate Gym Game receives frequent fixes and server restarts, so training, food, cleaning, or machine interactions may require script updates after game changes.
1local Players = game:GetService("Players")2local RS = game:GetService("ReplicatedStorage")3local UIS = game:GetService("UserInputService")4local VIM = game:GetService("VirtualInputManager")56local player = Players.LocalPlayer7local playerGui = player:WaitForChild("PlayerGui")89local function rem(name)10 return RS:FindFirstChild(name)11end1213local WorkoutEvent = rem("WorkoutEvent")14local WorkoutStateEvent = rem("WorkoutStateEvent")15local WorkoutRepResult = rem("WorkoutRepResult")16local GymMachineEvent = rem("GymMachineEvent")17local SupplementConsume = rem("SupplementConsume")18local HackSquatEvent = rem("HackSquatEvent")19local AbsCrunchEvent = rem("AbsCrunchEvent")20local PreacherCurlEvent = rem("PreacherCurlEvent")21local PullDipEvent = rem("PullDipEvent")22local YogaExerciseEvent = rem("YogaExerciseEvent")23local SeatedLegCurlEvent = rem("SeatedLegCurlEvent")24local PecFlyEvent = rem("PecFlyEvent")25local AdjustableSeatEvent = rem("AdjustableSeatEvent")26local CableStackEvent = rem("CableStackEvent")27local CashShopPurchase = rem("CashShopPurchase")28local CashShopOpen = rem("CashShopOpen")29local AutoWeightEvent = rem("AutoWeightEvent")30local AddPlateEvent = rem("AddPlateEvent")31local RemovePlatesEvent = rem("RemovePlatesEvent")32local SetDumbbellWeightEvent = rem("SetDumbbellWeightEvent")33local SetTricepWeightEvent = rem("SetTricepWeightEvent")3435local CashShopConfig, TrainingConfig, AutoWeightConfig, GymStaminaMod36pcall(function()37 CashShopConfig = require(RS:WaitForChild("CashShopConfig", 2))38end)39pcall(function()40 TrainingConfig = require(RS:WaitForChild("GymTrainingConfig", 2))41end)42pcall(function()43 AutoWeightConfig = require(RS:WaitForChild("AutoWeightConfig", 2))44end)45pcall(function()46 GymStaminaMod = require(RS:WaitForChild("GymStamina", 2))47end)4849local MACHINES = {50 { id = "PecFly", label = "Pec Fly", match = { "pectoral", "pecfly", "reverse fly" }, remote = PecFlyEvent },51 { id = "LegCurl", label = "Seated Leg Curl", match = { "seatedlegcurl", "legcurl" }, remote = SeatedLegCurlEvent },52 { id = "PullBar", label = "Pull / Dip Bar", match = { "pullbar" }, remote = PullDipEvent },53 { id = "Abs", label = "Abs Crunch", match = { "abscrunch" }, remote = AbsCrunchEvent },54 { id = "Seat", label = "Adjustable Seat", match = { "adjustableseat", "benchprop" }, remote = AdjustableSeatEvent },55 { id = "Yoga", label = "Yoga Mat", match = { "yogamat" }, remote = YogaExerciseEvent },56 { id = "Cable", label = "Multi Cable", match = { "multicable" }, remote = CableStackEvent },57 { id = "Squat", label = "Squat Rack", match = { "squatonly" }, remote = GymMachineEvent },58 { id = "Bench", label = "Bench", match = { "benchonly" }, remote = GymMachineEvent },59 { id = "Preacher", label = "Preacher Curl", match = { "preachercurl" }, remote = PreacherCurlEvent },60 { id = "HackSquat", label = "Hack Squat", match = { "hacksquat" }, remote = HackSquatEvent },61 { id = "Deadlift", label = "Deadlift", match = { "deadlift" }, remote = GymMachineEvent },62 { id = "Dumbbell", label = "Dumbbells", match = { "pro rdb", "dumbbell" }, remote = nil },63}6465local BUY_ITEM_ID = "chicken_rice"66local BUY_PRICE = 256768local cfg = {69 AutoTrain = false,70 AutoRep = true,71 AutoClean = false,72 AutoEat = false,73 AutoBuyFood = false,74 SkipBusy = true,75 HypertrophyWeight = true,76 LeaveToRest = true,77 MinCalories = 3000,78 RestBelowPct = 0.22,79 RestUntilPct = 0.92,80 TrainDelay = 0.25,81 RepDelay = 0.12,82 CleanDelay = 0.05,83 EatDelay = 0.85,84 BuyDelay = 0.8,85 Machine = {},86}8788for _, m in ipairs(MACHINES) do89 cfg.Machine[m.id] = true90end9192local running, threads = {}, {}93local statusText = "ready"94local uiRefreshers = {}9596local function fire(remote, ...)97 if not remote then return end98 local n = select("#", ...)99 local args = { ... }100 pcall(function()101 remote:FireServer(table.unpack(args, 1, n))102 end)103end104105local function firePrompt(prompt, holdExtra)106 if not prompt or not prompt:IsA("ProximityPrompt") then return false end107 if prompt.Enabled == false then return false end108109 local oldHold = prompt.HoldDuration110 local oldDist = prompt.MaxActivationDistance111 local oldLos = prompt.RequiresLineOfSight112113 pcall(function()114 prompt.MaxActivationDistance = math.max(oldDist, 30)115 prompt.RequiresLineOfSight = false116 end)117118 local holdTime = math.max(oldHold or 0, 0) + (holdExtra or 0.15)119 pcall(function()120 prompt:InputHoldBegin()121 end)122 task.wait(holdTime)123 pcall(function()124 prompt:InputHoldEnd()125 end)126127 pcall(function()128 if fireproximityprompt then129 fireproximityprompt(prompt)130 local saved = prompt.HoldDuration131 prompt.HoldDuration = 0132 fireproximityprompt(prompt)133 prompt.HoldDuration = saved134 end135 end)136137 pcall(function()138 if getconnections then139 for _, sig in ipairs({ "Triggered", "PromptButtonHoldBegan", "PromptButtonHoldEnded" }) do140 local ev = prompt[sig]141 if typeof(ev) == "RBXScriptSignal" then142 for _, c in ipairs(getconnections(ev)) do143 pcall(function()144 if c.Fire then145 c:Fire(player)146 elseif c.Function then147 c.Function(player)148 end149 end)150 end151 end152 end153 end154 end)155156 pcall(function()157 prompt.MaxActivationDistance = oldDist158 prompt.RequiresLineOfSight = oldLos159 prompt.HoldDuration = oldHold160 end)161 return true162end163164local function getHRP()165 local c = player.Character166 return c and c:FindFirstChild("HumanoidRootPart")167end168169local function getHum()170 local c = player.Character171 return c and c:FindFirstChildOfClass("Humanoid")172end173174local function tpTo(part, yOffset)175 local hrp = getHRP()176 if not (hrp and part) then return end177 local cf = part:IsA("BasePart") and part.CFrame or (part:IsA("Model") and part:GetPivot())178 if not cf then return end179 pcall(function()180 hrp.AssemblyLinearVelocity = Vector3.zero181 hrp.AssemblyAngularVelocity = Vector3.zero182 hrp.CFrame = cf * CFrame.new(0, yOffset or 3, 0)183 end)184end185186local function clickCenter()187 local cam = workspace.CurrentCamera188 local vp = cam and cam.ViewportSize or Vector2.new(960, 540)189 local x, y = vp.X / 2, vp.Y / 2190 pcall(function()191 VIM:SendMouseButtonEvent(x, y, 0, true, game, 1)192 task.wait(0.01)193 VIM:SendMouseButtonEvent(x, y, 0, false, game, 1)194 end)195end196197local function clickButtonsMatching(pred)198 for _, gui in ipairs(playerGui:GetChildren()) do199 if gui:IsA("ScreenGui") and gui.Enabled ~= false then200 for _, b in ipairs(gui:GetDescendants()) do201 if b:IsA("TextButton") or b:IsA("ImageButton") then202 local t = string.lower((b.Text or "") .. " " .. b.Name)203 if pred(t, b) then204 pcall(function()205 if firesignal then206 firesignal(b.MouseButton1Click)207 if b.Activated then firesignal(b.Activated) end208 end209 end)210 end211 end212 end213 end214 end215end216217local function startLoop(key, fn)218 if threads[key] then return end219 running[key] = true220 threads[key] = task.spawn(function()221 while running[key] do222 local ok, err = pcall(fn)223 if not ok then224 warn("[GymAuto]", key, err)225 statusText = "err: " .. tostring(err)226 task.wait(0.5)227 end228 end229 threads[key] = nil230 end)231end232233local function setFeature(key, on, fn)234 cfg[key] = on235 if on then236 startLoop(key, fn)237 else238 running[key] = false239 end240end241242local function refreshAllUI()243 for _, fn in ipairs(uiRefreshers) do244 pcall(fn)245 end246end247248local function parseNumber(text)249 if not text then return nil end250 local num = string.match(tostring(text), "([%d%,%.]+)")251 if not num then return nil end252 return tonumber((string.gsub(num, ",", "")))253end254255local function getCalories()256 for _, key in ipairs({ "Calories", "Calorie", "kcal", "Kcal" }) do257 local a = player:GetAttribute(key)258 if typeof(a) == "number" then return a end259 end260 local hud = playerGui:FindFirstChild("HUDGui")261 local main = hud and hud:FindFirstChild("MainHUD")262 local sec = main and main:FindFirstChild("CalorieSection")263 local val = sec and sec:FindFirstChild("CalorieValue")264 if val and val:IsA("TextLabel") then265 local n = parseNumber(val.Text)266 if n then return n end267 end268 return 0269end270271local function getCash()272 local hud = playerGui:FindFirstChild("HUDGui")273 local main = hud and hud:FindFirstChild("MainHUD")274 local row = main and main:FindFirstChild("CashRow")275 local val = row and row:FindFirstChild("CashValue")276 if val and val:IsA("TextLabel") then277 local n = parseNumber(val.Text)278 if n then return n end279 end280 local a = player:GetAttribute("Cash")281 if typeof(a) == "number" then return a end282 return 0283end284285local function getStamina()286 local gs = player:FindFirstChild("GymStats")287 if not gs then return 0, 100 end288 local s = gs:FindFirstChild("Stamina")289 local m = gs:FindFirstChild("MaxStamina")290 local cur = (s and s:IsA("NumberValue") and s.Value) or 0291 local max = (m and m:IsA("NumberValue") and m.Value) or 100292 if max <= 0 then max = 100 end293 return cur, max294end295296local function staminaPct()297 local s, m = getStamina()298 return s / m, s, m299end300301local function needsCalories()302 return getCalories() < (cfg.MinCalories or 0)303end304305local function nameMatches(name, patterns)306 local n = string.lower(name or "")307 for _, p in ipairs(patterns) do308 if string.find(n, p, 1, true) then return true end309 end310 return false311end312313local function getMachineDef(model, objectText)314 for _, def in ipairs(MACHINES) do315 if cfg.Machine[def.id] then316 if model and nameMatches(model.Name, def.match) then return def end317 if objectText and nameMatches(objectText, def.match) then return def end318 end319 end320 return nil321end322323local function isBusyPrompt(prompt)324 return string.find(string.lower(prompt.ObjectText or ""), "in use", 1, true) ~= nil325end326327-- ===== FOOD =====328local function findFoodTool()329 local function scan(container)330 if not container then return nil end331 for _, t in ipairs(container:GetChildren()) do332 if t:IsA("Tool") then333 if string.find(string.lower(t.Name), "chicken", 1, true) or t:GetAttribute("FoodEatWired") then334 return t335 end336 end337 end338 return nil339 end340 return scan(player.Character) or scan(player:FindFirstChild("Backpack"))341end342343local function hasFood()344 return findFoodTool() ~= nil345end346347local function eatFoodTool(tool)348 if not tool then return false end349 local hum = getHum()350 if hum then351 pcall(function()352 hum:EquipTool(tool)353 end)354 task.wait(0.15)355 end356 local bites = 1357 local br = tool:FindFirstChild("BitesRemaining")358 if br and br:IsA("ValueBase") then359 bites = math.max(1, tonumber(br.Value) or 1)360 end361 for _ = 1, bites do362 pcall(function()363 tool:Activate()364 end)365 clickCenter()366 fire(SupplementConsume, tool.Name)367 fire(SupplementConsume, "Chicken_rice")368 fire(SupplementConsume, "chicken_rice")369 task.wait(0.35)370 end371 return true372end373374local function buyChicken()375 local price = BUY_PRICE376 if CashShopConfig and CashShopConfig.getItem then377 local item = CashShopConfig.getItem(BUY_ITEM_ID)378 if item and item.price then price = item.price end379 end380 if getCash() < price then381 statusText = string.format("Buy: need $%d (have $%d)", price, getCash())382 return false383 end384385 local counter = workspace:FindFirstChild("CounterShop") or workspace:FindFirstChild("FoodStation", true)386 if counter then387 local part = counter:IsA("BasePart") and counter or counter:FindFirstChildWhichIsA("BasePart", true)388 if part then389 tpTo(part, 3)390 task.wait(0.1)391 end392 local prompt = counter:FindFirstChildWhichIsA("ProximityPrompt", true)393 if prompt then firePrompt(prompt, 0.05) end394 end395396 fire(CashShopOpen)397 fire(CashShopOpen, BUY_ITEM_ID)398 fire(CashShopPurchase, BUY_ITEM_ID)399 fire(CashShopPurchase, BUY_ITEM_ID, true)400 fire(CashShopPurchase, BUY_ITEM_ID, price)401 fire(CashShopPurchase, { id = BUY_ITEM_ID })402403 clickButtonsMatching(function(t)404 return string.find(t, "chicken", 1, true) and (string.find(t, "buy", 1, true) or string.find(t, "purchase", 1, true) or true)405 end)406407 statusText = "Buy: chicken_rice $" .. tostring(price)408 return true409end410411local function loopFoodManager()412 local cal = getCalories()413 if not needsCalories() then414 statusText = string.format("Food: OK cal=%d >= %d", cal, cfg.MinCalories)415 task.wait(1)416 return417 end418 if hasFood() then419 statusText = string.format("Food: eating | cal=%d < %d", cal, cfg.MinCalories)420 eatFoodTool(findFoodTool())421 task.wait(cfg.EatDelay)422 return423 end424 statusText = string.format("Food: buying | cal=%d < %d", cal, cfg.MinCalories)425 buyChicken()426 task.wait(cfg.BuyDelay)427 if hasFood() then428 eatFoodTool(findFoodTool())429 task.wait(cfg.EatDelay)430 end431end432433local function loopBuyFood()434 if not needsCalories() then435 statusText = string.format("Buy: OK cal=%d", getCalories())436 task.wait(1)437 return438 end439 if hasFood() then440 statusText = "Buy: already have food"441 task.wait(0.8)442 return443 end444 buyChicken()445 task.wait(cfg.BuyDelay)446end447448-- ===== CLEAN =====449local function collectTrash()450 local list = {}451 local root = workspace:FindFirstChild("ActiveTrash")452 if not root then return list end453 for _, prompt in ipairs(root:GetDescendants()) do454 if prompt:IsA("ProximityPrompt") and prompt.Enabled ~= false then455 local a = string.lower(prompt.ActionText or "")456 if a == "clean" or string.find(a, "clean", 1, true) then457 local part = prompt.Parent458 if not (part and part:IsA("BasePart")) then459 part = prompt:FindFirstAncestorWhichIsA("BasePart")460 end461 list[#list + 1] = { prompt = prompt, part = part }462 end463 end464 end465 return list466end467468local function cleanOne(item)469 if not item or not item.prompt then return end470 if item.part then471 tpTo(item.part, 2.2)472 task.wait(0.12)473 local hrp = getHRP()474 if hrp then475 pcall(function()476 hrp.CFrame = item.part.CFrame * CFrame.new(0, 2.5, 1.5)477 end)478 task.wait(0.08)479 end480 end481 statusText = "Clean: " .. tostring(item.prompt.ObjectText or "trash")482 firePrompt(item.prompt, 0.2)483 task.wait(0.05)484 firePrompt(item.prompt, 0.2)485end486487local function loopClean()488 local trash = collectTrash()489 if #trash == 0 then490 statusText = "Clean: no trash"491 task.wait(0.7)492 return493 end494 for _, item in ipairs(trash) do495 if not running.AutoClean then break end496 cleanOne(item)497 task.wait(cfg.CleanDelay)498 end499end500501-- ===== TRAIN / HYPERTROPHY / REST =====502local function leaveExercise()503 clickButtonsMatching(function(t)504 return string.find(t, "leave", 1, true) or string.find(t, "exit", 1, true) or string.find(t, "stop", 1, true)505 end)506 fire(WorkoutStateEvent, "Leave")507 fire(WorkoutStateEvent, "End")508 fire(GymMachineEvent, "Leave")509 fire(GymMachineEvent, "End")510end511512local function resolveExerciseDict()513 local session = player:GetAttribute("SessionExercise")514 if typeof(session) == "string" and session ~= "" then515 if TrainingConfig and TrainingConfig.EXERCISE_TO_DICT then516 return TrainingConfig.EXERCISE_TO_DICT[session] or session, session517 end518 return session, session519 end520 return nil, nil521end522523local function resolveLiftStat(dictName)524 local active = player:GetAttribute("ActiveIdeal")525 if typeof(active) == "number" and active > 0 then526 return active527 end528 if not (TrainingConfig and dictName) then return nil end529 local cfgEx = TrainingConfig.TrainingConfig and TrainingConfig.TrainingConfig[dictName]530 local statName = cfgEx and cfgEx.idealLiftStat531 if not statName then return nil end532 local liftStats = player:FindFirstChild("LiftStats")533 local gymStats = player:FindFirstChild("GymStats")534 local v = (liftStats and liftStats:FindFirstChild(statName)) or (gymStats and gymStats:FindFirstChild(statName))535 if v and v:IsA("NumberValue") then536 return math.max(1, v.Value)537 end538 return nil539end540541local function zoneAtWeight(dictName, kg, liftStat)542 if not TrainingConfig then return nil end543 local ok, zone = pcall(function()544 if TrainingConfig.getTrainingZone then545 return TrainingConfig.getTrainingZone(dictName, kg, liftStat, liftStat)546 end547 if TrainingConfig.getRawZoneAtWeight then548 return TrainingConfig.getRawZoneAtWeight(dictName, kg, liftStat, liftStat)549 end550 return nil551 end)552 return ok and zone or nil553end554555local function pickHypertrophyKg(dictName, liftStat)556 if not (TrainingConfig and dictName and liftStat) then return nil end557558 local ideal559 pcall(function()560 ideal = TrainingConfig.getHypertrophyIdeal(dictName, liftStat)561 end)562563 local presets = {}564 pcall(function()565 presets = TrainingConfig.getLiftableWeightPresets(dictName, liftStat) or {}566 end)567568 local bestHyp, bestDist569 for _, kg in ipairs(presets) do570 local zone = zoneAtWeight(dictName, kg, liftStat)571 if zone == "Hypertrophy" then572 local dist = ideal and math.abs(kg - ideal) or 0573 if not bestHyp or dist < (bestDist or 1e9) - 0.001 or (math.abs(dist - (bestDist or 0)) < 0.001 and kg > bestHyp) then574 bestHyp, bestDist = kg, dist575 end576 end577 end578 if bestHyp then return bestHyp, ideal end579580 if ideal then581 local closest582 pcall(function()583 closest = TrainingConfig.getClosestLiftablePresetKg(dictName, liftStat, ideal)584 end)585 return closest or ideal, ideal586 end587 return nil, nil588end589590local function applyWeightKg(kg, dictName)591 if not kg then return end592 fire(RemovePlatesEvent)593 fire(RemovePlatesEvent, true)594 fire(AddPlateEvent, kg)595 fire(AddPlateEvent, kg, dictName)596 fire(AddPlateEvent, { weight = kg })597 fire(SetDumbbellWeightEvent, kg)598 fire(SetDumbbellWeightEvent, kg / 2) -- per-hand sometimes599 fire(SetTricepWeightEvent, kg)600 fire(CableStackEvent, kg)601 fire(CableStackEvent, "SetWeight", kg)602 fire(GymMachineEvent, "SetWeight", kg)603 fire(GymMachineEvent, kg)604 fire(WorkoutStateEvent, "SetWeight", kg)605end606607local function enableHypertrophyAutoWeight()608 if AutoWeightConfig then609 pcall(function()610 player:SetAttribute(AutoWeightConfig.ATTR_ENABLED, true)611 player:SetAttribute(AutoWeightConfig.ATTR_ZONE, AutoWeightConfig.ZONE_HYPERTROPHY or "Hypertrophy")612 end)613 else614 pcall(function()615 player:SetAttribute("AutoWeightEnabled", true)616 player:SetAttribute("AutoWeightZone", "Hypertrophy")617 end)618 end619620 fire(AutoWeightEvent, "Hypertrophy")621 fire(AutoWeightEvent, true)622 fire(AutoWeightEvent, true, "Hypertrophy")623 fire(AutoWeightEvent, { enabled = true, zone = "Hypertrophy" })624 fire(AutoWeightEvent, { Zone = "Hypertrophy", Enabled = true })625626 clickButtonsMatching(function(t)627 return string.find(t, "hypertrophy", 1, true)628 end)629end630631local function applyHypertrophyWeight()632 if not cfg.HypertrophyWeight then return nil end633 enableHypertrophyAutoWeight()634 task.wait(0.15)635636 local dictName = resolveExerciseDict()637 local liftStat = resolveLiftStat(dictName)638 local kg, ideal = pickHypertrophyKg(dictName, liftStat)639 if kg then640 applyWeightKg(kg, dictName)641 statusText = string.format("Weight: %.1fkg Hypertrophy (ideal %.1f)", kg, ideal or kg)642 else643 statusText = "Weight: AutoWeight Hypertrophy (no preset)"644 end645 -- click again after weight UI opens646 task.wait(0.1)647 enableHypertrophyAutoWeight()648 return kg649end650651local function restForStamina()652 local pct, s, m = staminaPct()653 if pct >= cfg.RestUntilPct then return end654655 if cfg.LeaveToRest then656 leaveExercise()657 end658659 while running.AutoTrain do660 pct, s, m = staminaPct()661 statusText = string.format("Rest: stamina %.0f/%.0f (need %.0f%%)", s, m, cfg.RestUntilPct * 100)662 if pct >= cfg.RestUntilPct then663 break664 end665 task.wait(0.3)666 end667end668669local function doReps(def)670 if not cfg.AutoRep then return end671 fire(WorkoutEvent)672 fire(WorkoutEvent, "Rep")673 fire(WorkoutEvent, "Click")674 fire(WorkoutStateEvent, "Rep")675 fire(WorkoutRepResult, true)676 fire(GymMachineEvent, "Rep")677 if def and def.remote then678 fire(def.remote)679 fire(def.remote, "Rep")680 fire(def.remote, "Click")681 end682 clickCenter()683end684685local function canAffordAnotherRep()686 if GymStaminaMod and GymStaminaMod.canAffordRepForPlayer then687 local dictName, session = resolveExerciseDict()688 local weight = nil689 if GymStaminaMod.resolveSessionWeight then690 local ok, w = pcall(function()691 return select(2, GymStaminaMod.resolveSessionWeight(player))692 end)693 if ok then weight = w end694 end695 local ideal = player:GetAttribute("ActiveIdeal")696 if typeof(ideal) ~= "number" then ideal = resolveLiftStat(dictName) end697 local ok, can = pcall(function()698 return GymStaminaMod.canAffordRepForPlayer(player, session or dictName, weight or 0, ideal or 0)699 end)700 if ok and can ~= nil then return can end701 end702 local pct = staminaPct()703 return pct >= cfg.RestBelowPct704end705706local function collectTrainTargets()707 local list = {}708 for _, prompt in ipairs(workspace:GetDescendants()) do709 if prompt:IsA("ProximityPrompt") and prompt.Enabled ~= false then710 local a = string.lower(prompt.ActionText or "")711 if a == "use" or a == "use machine" or a == "yoga" or a == "pick up" then712 if not (cfg.SkipBusy and isBusyPrompt(prompt)) then713 local model = prompt:FindFirstAncestorOfClass("Model")714 local def = getMachineDef(model, prompt.ObjectText)715 if def then716 local part = prompt.Parent717 if not (part and part:IsA("BasePart")) then718 part = model and model:FindFirstChildWhichIsA("BasePart", true)719 end720 list[#list + 1] = { prompt = prompt, model = model, part = part, def = def }721 end722 end723 end724 end725 end726 return list727end728729local trainIndex = 1730local function loopTrain()731 -- rest first if already drained732 local pct = staminaPct()733 if pct < cfg.RestBelowPct then734 restForStamina()735 if not running.AutoTrain then return end736 end737738 local targets = collectTrainTargets()739 if #targets == 0 then740 statusText = "Train: no free machines (check filters)"741 task.wait(1)742 return743 end744745 local t = targets[((trainIndex - 1) % #targets) + 1]746 trainIndex += 1747748 statusText = "Train: " .. t.def.label749 if t.part then750 tpTo(t.part, 3)751 task.wait(0.1)752 end753 firePrompt(t.prompt, 0.05)754755 -- wait for session756 for _ = 1, 20 do757 if player:GetAttribute("InGymExercise") == true or player:GetAttribute("SessionExercise") then758 break759 end760 task.wait(0.05)761 end762763 local kg = applyHypertrophyWeight()764 task.wait(0.2)765 -- re-apply once plates UI exists766 if cfg.HypertrophyWeight then767 applyHypertrophyWeight()768 end769770 local repsDone = 0771 local maxReps = 40772 while running.AutoTrain and repsDone < maxReps do773 pct = staminaPct()774 if pct < cfg.RestBelowPct or not canAffordAnotherRep() then775 statusText = string.format("Train: stamina low after %d reps", repsDone)776 break777 end778 doReps(t.def)779 repsDone += 1780 if kg then781 statusText = string.format("Train: %s | %.1fkg Hyp | rep %d | stam %.0f%%", t.def.label, kg, repsDone, pct * 100)782 else783 statusText = string.format("Train: %s | Hyp | rep %d | stam %.0f%%", t.def.label, repsDone, pct * 100)784 end785 task.wait(cfg.RepDelay)786 end787788 restForStamina()789 task.wait(cfg.TrainDelay)790end791792-- ===== UI =====793local old = playerGui:FindFirstChild("GymAutoUI")794if old then old:Destroy() end795796local gui = Instance.new("ScreenGui")797gui.Name = "GymAutoUI"798gui.ResetOnSpawn = false799gui.ZIndexBehavior = Enum.ZIndexBehavior.Sibling800gui.Parent = playerGui801802local root = Instance.new("Frame")803root.Size = UDim2.fromOffset(460, 400)804root.Position = UDim2.new(0.5, -230, 0.5, -200)805root.BackgroundColor3 = Color3.fromRGB(22, 24, 28)806root.BorderSizePixel = 0807root.Active = true808root.Parent = gui809Instance.new("UICorner", root).CornerRadius = UDim.new(0, 10)810811local title = Instance.new("TextLabel")812title.Size = UDim2.new(1, -80, 0, 28)813title.Position = UDim2.fromOffset(12, 6)814title.BackgroundTransparency = 1815title.Font = Enum.Font.GothamBold816title.TextSize = 16817title.TextXAlignment = Enum.TextXAlignment.Left818title.TextColor3 = Color3.fromRGB(240, 240, 240)819title.Text = "Gym Auto v3"820title.Parent = root821822local status = Instance.new("TextLabel")823status.Size = UDim2.new(1, -24, 0, 18)824status.Position = UDim2.fromOffset(12, 32)825status.BackgroundTransparency = 1826status.Font = Enum.Font.Gotham827status.TextSize = 11828status.TextXAlignment = Enum.TextXAlignment.Left829status.TextColor3 = Color3.fromRGB(160, 170, 180)830status.Text = "ready"831status.Parent = root832833task.spawn(function()834 while gui.Parent do835 local s, m = getStamina()836 status.Text = string.format("%s | cal=%d $%d stam=%.0f/%.0f", statusText, getCalories(), getCash(), s, m)837 task.wait(0.25)838 end839end)840841do842 local dragging, dragStart, startPos843 title.InputBegan:Connect(function(input)844 if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then845 dragging = true846 dragStart = input.Position847 startPos = root.Position848 input.Changed:Connect(function()849 if input.UserInputState == Enum.UserInputState.End then dragging = false end850 end)851 end852 end)853 UIS.InputChanged:Connect(function(input)854 if dragging and (input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch) then855 local d = input.Position - dragStart856 root.Position = UDim2.new(startPos.X.Scale, startPos.X.Offset + d.X, startPos.Y.Scale, startPos.Y.Offset + d.Y)857 end858 end)859end860861local closeBtn = Instance.new("TextButton")862closeBtn.Size = UDim2.fromOffset(28, 28)863closeBtn.Position = UDim2.new(1, -36, 0, 6)864closeBtn.BackgroundColor3 = Color3.fromRGB(50, 40, 40)865closeBtn.Text = "X"866closeBtn.TextColor3 = Color3.fromRGB(255, 200, 200)867closeBtn.Font = Enum.Font.GothamBold868closeBtn.TextSize = 14869closeBtn.Parent = root870Instance.new("UICorner", closeBtn).CornerRadius = UDim.new(0, 6)871closeBtn.MouseButton1Click:Connect(function()872 for k in pairs(running) do running[k] = false end873 gui:Destroy()874end)875876local tabs = Instance.new("Frame")877tabs.Size = UDim2.new(0, 90, 1, -58)878tabs.Position = UDim2.fromOffset(8, 54)879tabs.BackgroundColor3 = Color3.fromRGB(16, 18, 22)880tabs.BorderSizePixel = 0881tabs.Parent = root882Instance.new("UICorner", tabs).CornerRadius = UDim.new(0, 8)883Instance.new("UIListLayout", tabs).Padding = UDim.new(0, 4)884local tabPad = Instance.new("UIPadding", tabs)885tabPad.PaddingTop = UDim.new(0, 6)886tabPad.PaddingLeft = UDim.new(0, 6)887tabPad.PaddingRight = UDim.new(0, 6)888889local pages = Instance.new("Frame")890pages.Size = UDim2.new(1, -114, 1, -58)891pages.Position = UDim2.fromOffset(106, 54)892pages.BackgroundColor3 = Color3.fromRGB(16, 18, 22)893pages.BorderSizePixel = 0894pages.Parent = root895Instance.new("UICorner", pages).CornerRadius = UDim.new(0, 8)896897local pageFrames = {}898899local function makePage(name)900 local f = Instance.new("ScrollingFrame")901 f.Name = name902 f.Size = UDim2.fromScale(1, 1)903 f.BackgroundTransparency = 1904 f.BorderSizePixel = 0905 f.ScrollBarThickness = 4906 f.AutomaticCanvasSize = Enum.AutomaticSize.Y907 f.CanvasSize = UDim2.fromOffset(0, 0)908 f.Visible = false909 f.Parent = pages910 local lay = Instance.new("UIListLayout", f)911 lay.Padding = UDim.new(0, 6)912 lay.SortOrder = Enum.SortOrder.LayoutOrder913 local pad = Instance.new("UIPadding", f)914 pad.PaddingTop = UDim.new(0, 8)915 pad.PaddingBottom = UDim.new(0, 8)916 pad.PaddingLeft = UDim.new(0, 8)917 pad.PaddingRight = UDim.new(0, 8)918 pageFrames[name] = f919 return f920end921922local function selectTab(name)923 for n, f in pairs(pageFrames) do924 f.Visible = (n == name)925 end926 for _, b in ipairs(tabs:GetChildren()) do927 if b:IsA("TextButton") then928 b.BackgroundColor3 = (b.Name == name) and Color3.fromRGB(55, 120, 90) or Color3.fromRGB(30, 34, 40)929 end930 end931end932933local function addTab(name, order)934 local b = Instance.new("TextButton")935 b.Name = name936 b.Size = UDim2.new(1, 0, 0, 28)937 b.BackgroundColor3 = Color3.fromRGB(30, 34, 40)938 b.Text = name939 b.TextColor3 = Color3.fromRGB(230, 230, 230)940 b.Font = Enum.Font.GothamBold941 b.TextSize = 12942 b.LayoutOrder = order943 b.Parent = tabs944 Instance.new("UICorner", b).CornerRadius = UDim.new(0, 6)945 b.MouseButton1Click:Connect(function()946 selectTab(name)947 end)948 makePage(name)949end950951local function sectionLabel(page, text)952 local l = Instance.new("TextLabel")953 l.Size = UDim2.new(1, -8, 0, 18)954 l.BackgroundTransparency = 1955 l.Font = Enum.Font.GothamBold956 l.TextSize = 12957 l.TextColor3 = Color3.fromRGB(120, 200, 160)958 l.TextXAlignment = Enum.TextXAlignment.Left959 l.Text = text960 l.Parent = page961end962963local function makeToggle(page, label, get, set)964 local b = Instance.new("TextButton")965 b.Size = UDim2.new(1, -8, 0, 28)966 b.BackgroundColor3 = Color3.fromRGB(35, 40, 48)967 b.TextColor3 = Color3.fromRGB(230, 230, 230)968 b.Font = Enum.Font.Gotham969 b.TextSize = 13970 b.TextXAlignment = Enum.TextXAlignment.Left971 b.Parent = page972 Instance.new("UICorner", b).CornerRadius = UDim.new(0, 6)973 local pad = Instance.new("UIPadding", b)974 pad.PaddingLeft = UDim.new(0, 10)975976 local function refresh()977 local on = get()978 b.Text = (on and "[ON] " or "[OFF] ") .. label979 b.BackgroundColor3 = on and Color3.fromRGB(40, 90, 60) or Color3.fromRGB(35, 40, 48)980 end981 uiRefreshers[#uiRefreshers + 1] = refresh982 refresh()983 b.MouseButton1Click:Connect(function()984 set(not get())985 refresh()986 end)987 return b988end989990local function feature(page, label, key, fn)991 makeToggle(page, label, function()992 return cfg[key]993 end, function(on)994 setFeature(key, on, fn)995 end)996end997998local function makeActionBtn(page, text, color, fn)999 local b = Instance.new("TextButton")1000 b.Size = UDim2.new(1, -8, 0, 28)1001 b.BackgroundColor3 = color1002 b.Text = text1003 b.TextColor3 = Color3.fromRGB(240, 240, 240)1004 b.Font = Enum.Font.GothamBold1005 b.TextSize = 121006 b.Parent = page1007 Instance.new("UICorner", b).CornerRadius = UDim.new(0, 6)1008 b.MouseButton1Click:Connect(fn)1009 return b1010end10111012addTab("Main", 1)1013addTab("Train", 2)1014addTab("Food", 3)1015addTab("Clean", 4)1016addTab("More", 5)10171018local main, train, food, clean, more = pageFrames.Main, pageFrames.Train, pageFrames.Food, pageFrames.Clean, pageFrames.More10191020sectionLabel(main, "QUICK")1021feature(main, "Auto Train (Hypertrophy + rest)", "AutoTrain", loopTrain)1022feature(main, "Auto Clean (cash)", "AutoClean", loopClean)1023feature(main, "Auto Food (by calories)", "AutoEat", loopFoodManager)1024makeToggle(main, "Skip busy machines", function()1025 return cfg.SkipBusy1026end, function(v)1027 cfg.SkipBusy = v1028end)1029makeToggle(main, "Auto Rep while training", function()1030 return cfg.AutoRep1031end, function(v)1032 cfg.AutoRep = v1033end)1034makeToggle(main, "Force Hypertrophy weight", function()1035 return cfg.HypertrophyWeight1036end, function(v)1037 cfg.HypertrophyWeight = v1038end)1039makeToggle(main, "Leave machine to rest stamina", function()1040 return cfg.LeaveToRest1041end, function(v)1042 cfg.LeaveToRest = v1043end)10441045sectionLabel(train, "MACHINE FILTERS")1046for _, m in ipairs(MACHINES) do1047 makeToggle(train, m.label, function()1048 return cfg.Machine[m.id] == true1049 end, function(v)1050 cfg.Machine[m.id] = v and true or false1051 end)1052end10531054makeActionBtn(train, "Enable ALL machines", Color3.fromRGB(45, 90, 60), function()1055 for _, m in ipairs(MACHINES) do1056 cfg.Machine[m.id] = true1057 end1058 refreshAllUI()1059 statusText = "filters: all ON"1060end)1061makeActionBtn(train, "Disable ALL machines", Color3.fromRGB(90, 50, 50), function()1062 for _, m in ipairs(MACHINES) do1063 cfg.Machine[m.id] = false1064 end1065 refreshAllUI()1066 statusText = "filters: all OFF"1067end)10681069sectionLabel(train, "STAMINA REST")1070local restBelowBtn = Instance.new("TextButton")1071restBelowBtn.Size = UDim2.new(1, -8, 0, 26)1072restBelowBtn.BackgroundColor3 = Color3.fromRGB(40, 50, 65)1073restBelowBtn.TextColor3 = Color3.fromRGB(230, 230, 230)1074restBelowBtn.Font = Enum.Font.Gotham1075restBelowBtn.TextSize = 121076restBelowBtn.Parent = train1077Instance.new("UICorner", restBelowBtn).CornerRadius = UDim.new(0, 6)1078local function refreshRestBelow()1079 restBelowBtn.Text = string.format("Rest when stamina < %d%% (click +5)", math.floor(cfg.RestBelowPct * 100 + 0.5))1080end1081refreshRestBelow()1082restBelowBtn.MouseButton1Click:Connect(function()1083 cfg.RestBelowPct += 0.051084 if cfg.RestBelowPct > 0.8 then cfg.RestBelowPct = 0.1 end1085 refreshRestBelow()1086end)10871088local restUntilBtn = Instance.new("TextButton")1089restUntilBtn.Size = UDim2.new(1, -8, 0, 26)1090restUntilBtn.BackgroundColor3 = Color3.fromRGB(40, 50, 65)1091restUntilBtn.TextColor3 = Color3.fromRGB(230, 230, 230)1092restUntilBtn.Font = Enum.Font.Gotham1093restUntilBtn.TextSize = 121094restUntilBtn.Parent = train1095Instance.new("UICorner", restUntilBtn).CornerRadius = UDim.new(0, 6)1096local function refreshRestUntil()1097 restUntilBtn.Text = string.format("Resume when stamina >= %d%% (click +5)", math.floor(cfg.RestUntilPct * 100 + 0.5))1098end1099refreshRestUntil()1100restUntilBtn.MouseButton1Click:Connect(function()1101 cfg.RestUntilPct += 0.051102 if cfg.RestUntilPct > 1 then cfg.RestUntilPct = 0.5 end1103 refreshRestUntil()1104end)11051106local trainHint = Instance.new("TextLabel")1107trainHint.Size = UDim2.new(1, -8, 0, 48)1108trainHint.BackgroundTransparency = 11109trainHint.TextWrapped = true1110trainHint.Font = Enum.Font.Gotham1111trainHint.TextSize = 111112trainHint.TextColor3 = Color3.fromRGB(150, 160, 170)1113trainHint.TextXAlignment = Enum.TextXAlignment.Left1114trainHint.Text = "Uses GymTrainingConfig presets in Hypertrophy zone.\nStamina does not regen during exercise — script leaves to rest."1115trainHint.Parent = train11161117sectionLabel(food, "CALORIE GATE")1118local calInfo = Instance.new("TextLabel")1119calInfo.Size = UDim2.new(1, -8, 0, 36)1120calInfo.BackgroundTransparency = 11121calInfo.TextWrapped = true1122calInfo.Font = Enum.Font.Gotham1123calInfo.TextSize = 111124calInfo.TextColor3 = Color3.fromRGB(160, 170, 180)1125calInfo.TextXAlignment = Enum.TextXAlignment.Left1126calInfo.Text = "If calories < Min → buy Chicken Rice ($25) if needed, then eat.\nIf calories >= Min → skip."1127calInfo.Parent = food11281129local minBtn = Instance.new("TextButton")1130minBtn.Size = UDim2.new(1, -8, 0, 28)1131minBtn.BackgroundColor3 = Color3.fromRGB(40, 50, 65)1132minBtn.TextColor3 = Color3.fromRGB(230, 230, 230)1133minBtn.Font = Enum.Font.GothamBold1134minBtn.TextSize = 121135minBtn.Parent = food1136Instance.new("UICorner", minBtn).CornerRadius = UDim.new(0, 6)1137local function refreshMin()1138 minBtn.Text = string.format("Min Calories: %d (LMB +500 / RMB -500)", cfg.MinCalories)1139end1140refreshMin()1141minBtn.MouseButton1Click:Connect(function()1142 cfg.MinCalories += 5001143 if cfg.MinCalories > 20000 then cfg.MinCalories = 500 end1144 refreshMin()1145end)1146minBtn.MouseButton2Click:Connect(function()1147 cfg.MinCalories = math.max(0, cfg.MinCalories - 500)1148 refreshMin()1149end)11501151feature(food, "Auto Food manager (eat+buy)", "AutoEat", loopFoodManager)1152feature(food, "Auto Buy only", "AutoBuyFood", loopBuyFood)1153makeActionBtn(food, "Buy chicken once", Color3.fromRGB(50, 80, 110), function()1154 task.spawn(buyChicken)1155end)1156makeActionBtn(food, "Eat chicken once", Color3.fromRGB(50, 80, 110), function()1157 task.spawn(function()1158 local tool = findFoodTool()1159 if tool then eatFoodTool(tool) else statusText = "no Chicken_rice in backpack" end1160 end)1161end)11621163sectionLabel(clean, "CLEANING = CASH")1164feature(clean, "Auto Clean trash", "AutoClean", loopClean)1165makeActionBtn(clean, "Clean once (all)", Color3.fromRGB(50, 80, 110), function()1166 task.spawn(function()1167 local trash = collectTrash()1168 statusText = "Clean once x" .. #trash1169 for _, item in ipairs(trash) do1170 cleanOne(item)1171 task.wait(0.1)1172 end1173 end)1174end)11751176sectionLabel(more, "DELAYS / DEBUG")1177local function delayBtn(label, key, step, minv, maxv)1178 local b = Instance.new("TextButton")1179 b.Size = UDim2.new(1, -8, 0, 26)1180 b.BackgroundColor3 = Color3.fromRGB(35, 40, 48)1181 b.TextColor3 = Color3.fromRGB(220, 220, 220)1182 b.Font = Enum.Font.Gotham1183 b.TextSize = 121184 b.Parent = more1185 Instance.new("UICorner", b).CornerRadius = UDim.new(0, 6)1186 local function refresh()1187 b.Text = string.format("%s: %.2fs", label, cfg[key])1188 end1189 refresh()1190 b.MouseButton1Click:Connect(function()1191 cfg[key] += step1192 if cfg[key] > maxv then cfg[key] = minv end1193 refresh()1194 end)1195end1196delayBtn("Train delay", "TrainDelay", 0.1, 0.1, 3)1197delayBtn("Rep delay", "RepDelay", 0.02, 0.05, 1)1198delayBtn("Clean delay", "CleanDelay", 0.05, 0.05, 2)1199delayBtn("Eat delay", "EatDelay", 0.1, 0.2, 3)1200delayBtn("Buy delay", "BuyDelay", 0.1, 0.3, 3)12011202makeActionBtn(more, "Leave exercise", Color3.fromRGB(90, 50, 50), leaveExercise)1203makeActionBtn(more, "Apply Hypertrophy weight now", Color3.fromRGB(50, 80, 110), function()1204 task.spawn(applyHypertrophyWeight)1205end)1206makeActionBtn(more, "Print debug", Color3.fromRGB(50, 60, 80), function()1207 local s, m = getStamina()1208 local dict = resolveExerciseDict()1209 print("[GymAuto] cal=", getCalories(), "cash=", getCash(), "stam=", s, m)1210 print("[GymAuto] exercise=", dict, "ActiveIdeal=", player:GetAttribute("ActiveIdeal"))1211 print("[GymAuto] food=", findFoodTool() and findFoodTool().Name or "none", "trash=", #collectTrash())1212 statusText = "printed debug"1213end)12141215selectTab("Main")1216print("[GymAuto v3] loaded — Hypertrophy weights + stamina rest")
Comments · …
Loading comments…