M
Description
full open source autogym (let me rest in peace)
GAME[UPDATE] Shigaku
UPDATEDOct 10, 2026
ACCESSKeyless
PLATFORMDesktop & Mobile
Script source Luau
-- shigaku autogym final update hopefully
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local GuiService = game:GetService("GuiService")
local VIM = game:GetService("VirtualInputManager")
local player = Players.LocalPlayer
local playerGui = player:WaitForChild("PlayerGui")
local enabled = true
local AUTO_LIFT = true -- press the prompt when it says "Lift"
local LIFT_COOLDOWN = 1.5 -- seconds between Lift presses
local DARK_MAX = 0.35 -- weight text darker than this = trainable (black), lighter = locked (grey)
local RETRY_DELAY = 0.35 -- Q/E mode: re-press if a box stays red this long
local PRESS_DELAY = 0.09 -- dumbbell: time between Q taps
local ZONE_MARGIN = 0.20 -- dumbbell: stop once the fill is this far (0-1) into the grey zone
local keys = { Q = Enum.KeyCode.Q, E = Enum.KeyCode.E }
local wasRed = { Q = false, E = false }
local lastPress = { Q = 0, E = 0 }
local boxes = { Q = nil, E = nil }
local bar = { fill = nil, zone = nil }
local lastZone = { left = nil, w = nil }
local mode = nil -- "alt" (Q/E boxes) or "bar" (dumbbell)
local liftStatus = "Lift: --"
local function isRed(c)
return c.R > 0.6 and c.G < 0.4 and c.B < 0.4
end
local function isZoneColor(d)
local c = d.BackgroundColor3
local mx = math.max(c.R, c.G, c.B)
local mn = math.min(c.R, c.G, c.B)
local t = d.BackgroundTransparency
local eff = mx * (1 - t) + 0.06 * t
return mx - mn < 0.08 and eff > 0.3 and eff < 0.95
end
local function isLetter(d, letter)
if not d:IsA("GuiObject") then return false end
if (d:IsA("TextLabel") or d:IsA("TextButton")) then
local t = d.Text:gsub("%s", ""):upper()
if t == letter then return true end
end
return d.Name:upper() == letter
end
local function visibleChain(d)
local o = d
while o and o ~= playerGui do
if o:IsA("GuiObject") and not o.Visible then return false end
if o:IsA("ScreenGui") and not o.Enabled then return false end
o = o.Parent
end
return o == playerGui
end
local function centerOf(d)
return Vector2.new(d.AbsolutePosition.X + d.AbsoluteSize.X / 2, d.AbsolutePosition.Y + d.AbsoluteSize.Y / 2)
end
local function onScreen(d)
if d.AbsoluteSize.X <= 0 or d.AbsoluteSize.Y <= 0 then return false end
local cam = workspace.CurrentCamera
if cam then
local c, vp = centerOf(d), cam.ViewportSize
if c.X < 0 or c.Y < 0 or c.X > vp.X or c.Y > vp.Y then return false end
end
local o = d
while o and o ~= playerGui do
if o:IsA("CanvasGroup") and o.GroupTransparency > 0.9 then return false end
o = o.Parent
end
return true
end
----------------------------------------------------------------------
-- dumbbell bar (red fill + grey zone)
----------------------------------------------------------------------
local function pickZone(anc, fill, q, qh, needVisible)
local fy = fill.AbsolutePosition.Y + fill.AbsoluteSize.Y / 2
local best, bestDist
for _, d in ipairs(anc:GetDescendants()) do
if d:IsA("GuiObject") and d ~= fill and not d:IsAncestorOf(q) and d ~= q
and d.BackgroundTransparency < 1 and isZoneColor(d)
and d.AbsoluteSize.X > 0 and d.AbsoluteSize.Y <= qh
and (not needVisible or visibleChain(d)) then
local dist = math.abs(d.AbsolutePosition.Y + d.AbsoluteSize.Y / 2 - fy)
if dist <= math.max(fill.AbsoluteSize.Y, 6) and (not bestDist or dist < bestDist) then
best, bestDist = d, dist
end
end
end
return best
end
local function findBar(q)
local qBox = q
local p = q.Parent
if p and p:IsA("GuiObject") and p.BackgroundTransparency < 1
and p.AbsoluteSize.X <= math.max(q.AbsoluteSize.X, 1) * 2.5 then
qBox = p
end
local qh = qBox.AbsoluteSize.Y
local cy = qBox.AbsolutePosition.Y + qh / 2
local anc = q.Parent
for _ = 1, 6 do
if not anc or anc == playerGui then break end
local fill, fillDist
for _, d in ipairs(anc:GetDescendants()) do
if d:IsA("GuiObject") and d ~= q and not d:IsAncestorOf(q) and not q:IsAncestorOf(d)
and visibleChain(d) and d.BackgroundTransparency < 1 and isRed(d.BackgroundColor3)
and d.AbsoluteSize.Y > 0 and d.AbsoluteSize.Y < qh * 0.6 then
local dist = math.abs(d.AbsolutePosition.Y + d.AbsoluteSize.Y / 2 - cy)
if not fillDist or dist < fillDist then fill, fillDist = d, dist end
end
end
if fill then
local zone = pickZone(anc, fill, q, qh, true) or pickZone(anc, fill, q, qh, false)
if zone then return fill, zone end
end
anc = anc.Parent
end
end
local function locate()
mode, boxes.Q, boxes.E, bar.fill, bar.zone = nil, nil, nil, nil, nil
local firstQ
for _, q in ipairs(playerGui:GetDescendants()) do
if isLetter(q, "Q") and visibleChain(q) then
firstQ = firstQ or q
local anc = q.Parent
for _ = 1, 6 do
if not anc or anc == playerGui then break end
for _, d in ipairs(anc:GetDescendants()) do
if d ~= q and isLetter(d, "E") and visibleChain(d) then
mode, boxes.Q, boxes.E = "alt", q, d
return
end
end
anc = anc.Parent
end
end
end
if firstQ then
local fill, zone = findBar(firstQ)
if fill and zone then
mode, boxes.Q, bar.fill, bar.zone = "bar", firstQ, fill, zone
lastZone.left, lastZone.w = zone.AbsolutePosition.X, zone.AbsoluteSize.X
end
end
end
local function colorRed(o)
if o:IsA("GuiObject") and o.BackgroundTransparency < 1 and isRed(o.BackgroundColor3) then
return true
end
if (o:IsA("ImageLabel") or o:IsA("ImageButton")) and isRed(o.ImageColor3) then
return true
end
return false
end
local function boxIsRed(obj)
if not obj or not obj.Parent then return false end
if colorRed(obj) then return true end
local p = obj.Parent
for _ = 1, 2 do
if p and p ~= playerGui and colorRed(p) then return true end
p = p and p.Parent
end
for _, c in ipairs(obj:GetChildren()) do
if colorRed(c) then return true end
end
return false
end
local function press(letter, obj)
lastPress[letter] = tick()
if obj and obj:IsA("GuiButton") and getconnections then
for _, c in ipairs(getconnections(obj.MouseButton1Click)) do pcall(c.Fire, c) end
for _, c in ipairs(getconnections(obj.Activated)) do pcall(c.Fire, c) end
end
VIM:SendKeyEvent(true, keys[letter], false, game)
task.wait(0.05)
VIM:SendKeyEvent(false, keys[letter], false, game)
end
----------------------------------------------------------------------
-- auto Lift (proximity prompt) + auto weight pick
----------------------------------------------------------------------
local prompts = {}
local function trackPrompt(d)
if d:IsA("ProximityPrompt") then prompts[d] = true end
end
for _, d in ipairs(workspace:GetDescendants()) do trackPrompt(d) end
workspace.DescendantAdded:Connect(trackPrompt)
workspace.DescendantRemoving:Connect(function(d) prompts[d] = nil end)
local function promptPos(p)
local par = p.Parent
if not par then return nil end
if par:IsA("BasePart") then return par.Position end
if par:IsA("Attachment") then return par.WorldPosition end
if par:IsA("Model") then return par:GetPivot().Position end
end
local function squash(s)
local r = s:gsub("%s", "")
return r:lower()
end
local function nearestPrompt()
local char = player.Character
local hrp = char and char:FindFirstChild("HumanoidRootPart")
if not hrp then return nil end
local best, bestDist
for p in pairs(prompts) do
if p.Parent and p.Enabled then
local isGym = p.Name:lower():find("gym") or squash(p.ActionText) == "lift"
local pos = isGym and promptPos(p)
if pos then
local dist = (pos - hrp.Position).Magnitude
if dist <= p.MaxActivationDistance + 2 and (not bestDist or dist < bestDist) then
best, bestDist = p, dist
end
end
end
end
return best
end
local function firePrompt(p)
if fireproximityprompt then
fireproximityprompt(p)
else
local key = p.KeyboardKeyCode
VIM:SendKeyEvent(true, key, false, game)
task.wait(p.HoldDuration + 0.1)
VIM:SendKeyEvent(false, key, false, game)
end
end
-- weight menu: several "NN LB" rows, black = trainable, grey = locked
local function scanWeights()
local count, distinct, best, bestNum = 0, {}, nil, -1
for _, d in ipairs(playerGui:GetDescendants()) do
if d:IsA("TextLabel") or d:IsA("TextButton") then
local n = d.Text:upper():match("^%s*(%d+)%s*LB%s*$")
if n and visibleChain(d) and onScreen(d) then
n = tonumber(n)
count = count + 1
distinct[n] = true
local c = d.TextColor3
local dark = math.max(c.R, c.G, c.B) < DARK_MAX and d.TextTransparency < 0.3
if dark and n > bestNum then best, bestNum = d, n end
end
end
end
local kinds = 0
for _ in pairs(distinct) do kinds = kinds + 1 end
if kinds >= 2 and best then return best, bestNum end
end
local function findButtonAt(label)
local c = centerOf(label)
local best, bestArea
local function consider(b)
if b:IsA("GuiButton") then
local p, s = b.AbsolutePosition, b.AbsoluteSize
if c.X >= p.X and c.X <= p.X + s.X and c.Y >= p.Y and c.Y <= p.Y + s.Y then
local area = s.X * s.Y
if not bestArea or area < bestArea then best, bestArea = b, area end
end
end
end
local o = label
for _ = 1, 4 do
if not o or o == playerGui then break end
consider(o)
for _, d in ipairs(o:GetDescendants()) do consider(d) end
o = o.Parent
end
return best
end
local function fireButton(b)
local fired = false
for _, sig in ipairs({ "Activated", "MouseButton1Click" }) do
for _, conn in ipairs(getconnections(b[sig])) do
pcall(conn.Fire, conn)
fired = true
end
end
return fired
end
local function tapAt(label)
local c = centerOf(label)
local sg = label:FindFirstAncestorWhichIsA("ScreenGui")
local y = c.Y
if not (sg and sg.IgnoreGuiInset) then y = y + GuiService:GetGuiInset().Y end
VIM:SendMouseButtonEvent(c.X, y, 0, true, game, 0)
task.wait(0.05)
VIM:SendMouseButtonEvent(c.X, y, 0, false, game, 0)
end
----------------------------------------------------------------------
-- toggle button + status
----------------------------------------------------------------------
local gui = Instance.new("ScreenGui")
gui.Name = "AutoQE"
gui.ResetOnSpawn = false
gui.Parent = (gethui and gethui()) or game:GetService("CoreGui")
local btn = Instance.new("TextButton")
btn.Size = UDim2.new(0, 160, 0, 62)
btn.Position = UDim2.new(0, 10, 0.5, 0)
btn.BackgroundColor3 = Color3.fromRGB(40, 160, 70)
btn.TextColor3 = Color3.new(1, 1, 1)
btn.Font = Enum.Font.GothamBold
btn.TextSize = 11
btn.Text = "Auto QE: ON"
btn.Active = true
btn.Draggable = true
btn.Parent = gui
Instance.new("UICorner", btn)
btn.MouseButton1Click:Connect(function()
enabled = not enabled
btn.BackgroundColor3 = enabled and Color3.fromRGB(40, 160, 70) or Color3.fromRGB(170, 50, 50)
end)
----------------------------------------------------------------------
-- main loop: Q/E + dumbbell bar
----------------------------------------------------------------------
local lastScan = 0
RunService.Heartbeat:Connect(function()
if not enabled then btn.Text = "Auto QE: OFF" return end
local stale
if mode == "alt" then
stale = not boxes.Q.Parent or not boxes.E.Parent
or not visibleChain(boxes.Q) or not visibleChain(boxes.E)
elseif mode == "bar" then
stale = not boxes.Q.Parent or not bar.fill.Parent
or not visibleChain(boxes.Q) or not visibleChain(bar.fill)
or tick() - lastScan > 1
else
stale = true
end
if stale and tick() - lastScan > 0.25 then
lastScan = tick()
locate()
wasRed.Q, wasRed.E = false, false
end
if mode == "bar" then
local zoneLeft, zoneW = lastZone.left, lastZone.w
if bar.zone and bar.zone.Parent then
zoneLeft, zoneW = bar.zone.AbsolutePosition.X, bar.zone.AbsoluteSize.X
lastZone.left, lastZone.w = zoneLeft, zoneW
end
if not zoneLeft then return end
local fillRight = bar.fill.AbsolutePosition.X + bar.fill.AbsoluteSize.X
local target = zoneLeft + zoneW * ZONE_MARGIN
if fillRight < target and tick() - lastPress.Q > PRESS_DELAY then
task.spawn(press, "Q", boxes.Q)
end
local state = "pushing"
if fillRight > zoneLeft + zoneW then state = "over"
elseif fillRight >= zoneLeft then state = "in zone" end
btn.Text = ("Auto QE: ON\nDumbbell: %s\n%s"):format(state, liftStatus)
return
end
local status = {}
for letter in pairs(keys) do
local obj = boxes[letter]
local red = boxIsRed(obj)
status[letter] = obj and (red and "red" or "--") or "none"
if red and (not wasRed[letter] or tick() - lastPress[letter] > RETRY_DELAY) then
task.spawn(press, letter, obj)
end
wasRed[letter] = red
end
btn.Text = ("Auto QE: ON\nQ:%s E:%s\n%s"):format(status.Q, status.E, liftStatus)
end)
----------------------------------------------------------------------
-- second loop: weight menu first, otherwise press Lift when it says Lift
----------------------------------------------------------------------
local weightAttempts, lastWeightTry, lastLift = 0, 0, 0
task.spawn(function()
while true do
task.wait(0.2)
if not enabled then
liftStatus = "Lift: OFF"
else
local label, num = scanWeights()
if label then
liftStatus = "Weight: " .. num .. " LB"
if tick() - lastWeightTry > 0.8 then
lastWeightTry = tick()
weightAttempts = weightAttempts + 1
local fired = false
if weightAttempts == 1 and getconnections then
local b = findButtonAt(label)
if b then fired = fireButton(b) end
end
if not fired then tapAt(label) end
end
else
weightAttempts = 0
local p = AUTO_LIFT and mode == nil and nearestPrompt()
if p then
liftStatus = "Lift: " .. p.ActionText
if squash(p.ActionText) == "lift" and tick() - lastLift > LIFT_COOLDOWN then
lastLift = tick()
task.spawn(firePrompt, p)
end
else
liftStatus = "Lift: --"
end
end
end
end
end)Review the source before using it. Executions count successful copies, capped at 10 per user and network per script in 24 hours.
Community discussion
0Start the conversation.


Your community, in one place