M
Description
auto play rochess best move nice gui
GAMERoChess!
UPDATEDOct 21, 2026
ACCESSKeyless
PLATFORMDesktop
Script source Luau
-- [[ BloxScripts Risk Notice ]]
-- This script has not been verified by BloxScripts.fun. 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 BloxScripts Risk Notice ]]
if _G.__BestMoveGUIRunning then
warn("[BestMoveGUI] already running")
return
end
_G.__BestMoveGUIRunning = true
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local AUTO_PLAY = true
_G.__BestMoveAutoPlay = AUTO_PLAY
local TIME_BUDGET = 2.0
local MAX_DEPTH = 40
local USE_VORTEX = true
local HINT_COLOR = Color3.fromRGB(150, 190, 70)
-- ===== =====
local ChessFolder = ReplicatedStorage:WaitForChild("Chess")
local ClientFolder = ReplicatedStorage:WaitForChild("ChessClient")
local Engine = require(ChessFolder:WaitForChild("Engine"))
local Bot = require(ChessFolder:WaitForChild("Bot"))
local VortexBot = nil
pcall(function() VortexBot = require(ChessFolder:WaitForChild("VortexBot")) end)
local App = require(ClientFolder:WaitForChild("App"))
local PROMO_MAP = { q = 5, r = 4, b = 3, n = 2 }
local LocalPlayer = Players.LocalPlayer
local oldGui = LocalPlayer:FindFirstChild("PlayerGui") and LocalPlayer.PlayerGui:FindFirstChild("BestMoveGUI")
if oldGui then oldGui:Destroy() end
local PlayerGui = LocalPlayer:WaitForChild("PlayerGui")
local ScreenGui = Instance.new("ScreenGui")
ScreenGui.Name = "BestMoveGUI"
ScreenGui.ResetOnSpawn = false
ScreenGui.ZIndexBehavior = Enum.ZIndexBehavior.Sibling
ScreenGui.Parent = PlayerGui
local Main = Instance.new("Frame")
Main.Name = "Main"
Main.Size = UDim2.new(0, 300, 0, 300)
Main.Position = UDim2.new(1, -320, 0, 20)
Main.BackgroundColor3 = Color3.fromRGB(24, 26, 32)
Main.BorderSizePixel = 0
Main.Parent = ScreenGui
local corner = Instance.new("UICorner"); corner.CornerRadius = UDim.new(0, 10); corner.Parent = Main
local stroke = Instance.new("UIStroke"); stroke.Color = Color3.fromRGB(60, 64, 72); stroke.Thickness = 1; stroke.Parent = Main
local TitleBar = Instance.new("Frame")
TitleBar.Name = "TitleBar"
TitleBar.Size = UDim2.new(1, 0, 0, 32)
TitleBar.BackgroundColor3 = Color3.fromRGB(32, 34, 42)
TitleBar.BorderSizePixel = 0
TitleBar.Parent = Main
local titleCorner = Instance.new("UICorner"); titleCorner.CornerRadius = UDim.new(0, 10); titleCorner.Parent = TitleBar
local Title = Instance.new("TextLabel")
Title.Size = UDim2.new(1, -40, 1, 0)
Title.Position = UDim2.new(0, 10, 0, 0)
Title.BackgroundTransparency = 1
Title.Text = "♟ Best Move"
Title.TextColor3 = Color3.fromRGB(230, 230, 240)
Title.Font = Enum.Font.GothamBold
Title.TextSize = 15
Title.TextXAlignment = Enum.TextXAlignment.Left
Title.Parent = TitleBar
local MinBtn = Instance.new("TextButton")
MinBtn.Size = UDim2.new(0, 28, 0, 24)
MinBtn.Position = UDim2.new(1, -32, 0, 4)
MinBtn.BackgroundColor3 = Color3.fromRGB(50, 52, 60)
MinBtn.Text = "—"
MinBtn.TextColor3 = Color3.fromRGB(230,230,240)
MinBtn.Font = Enum.Font.GothamBold
MinBtn.TextSize = 14
MinBtn.BorderSizePixel = 0
MinBtn.Parent = TitleBar
local minCorner = Instance.new("UICorner"); minCorner.CornerRadius = UDim.new(0,6); minCorner.Parent = MinBtn
--
local Content = Instance.new("Frame")
Content.Name = "Content"
Content.Size = UDim2.new(1, -16, 1, -40)
Content.Position = UDim2.new(0, 8, 0, 36)
Content.BackgroundTransparency = 1
Content.Parent = Main
local layout = Instance.new("UIListLayout")
layout.Padding = UDim.new(0, 6)
layout.SortOrder = Enum.SortOrder.LayoutOrder
layout.Parent = Content
local function makeLabel(text, size, color, bold)
local l = Instance.new("TextLabel")
l.Size = UDim2.new(1, 0, 0, size or 18)
l.BackgroundTransparency = 1
l.Text = text
l.TextColor3 = color or Color3.fromRGB(220,220,230)
l.Font = bold and Enum.Font.GothamBold or Enum.Font.Gotham
l.TextSize = 13
l.TextXAlignment = Enum.TextXAlignment.Left
l.TextWrapped = true
l.Parent = Content
return l
end
local function makeRow(labelText)
local row = Instance.new("Frame")
row.Name = "Row"
row.Size = UDim2.new(1, 0, 0, 26)
row.BackgroundTransparency = 1
row.Parent = Content
local lbl = Instance.new("TextLabel")
lbl.Size = UDim2.new(0.55, 0, 1, 0)
lbl.BackgroundTransparency = 1
lbl.Text = labelText
lbl.TextColor3 = Color3.fromRGB(200,200,210)
lbl.Font = Enum.Font.Gotham
lbl.TextSize = 13
lbl.TextXAlignment = Enum.TextXAlignment.Left
lbl.Parent = row
return row, lbl
end
--
local rowAP = makeRow("Auto-play:")
local AutoPlayBtn = Instance.new("TextButton")
AutoPlayBtn.Name = "AutoPlayBtn"
AutoPlayBtn.Size = UDim2.new(0.45, -4, 1, -2)
AutoPlayBtn.Position = UDim2.new(0.55, 4, 0, 1)
AutoPlayBtn.BackgroundColor3 = AUTO_PLAY and Color3.fromRGB(60, 130, 80) or Color3.fromRGB(130, 60, 60)
AutoPlayBtn.Text = AUTO_PLAY and "ON" or "OFF"
AutoPlayBtn.TextColor3 = Color3.fromRGB(255,255,255)
AutoPlayBtn.Font = Enum.Font.GothamBold
AutoPlayBtn.TextSize = 12
AutoPlayBtn.BorderSizePixel = 0
AutoPlayBtn.Parent = rowAP
local apc = Instance.new("UICorner"); apc.CornerRadius = UDim.new(0,6); apc.Parent = AutoPlayBtn
--
local rowT = makeRow("Time (s):")
local TimeBox = Instance.new("TextBox")
TimeBox.Size = UDim2.new(0.45, -4, 1, -2)
TimeBox.Position = UDim2.new(0.55, 4, 0, 1)
TimeBox.BackgroundColor3 = Color3.fromRGB(40, 42, 50)
TimeBox.Text = tostring(TIME_BUDGET)
TimeBox.TextColor3 = Color3.fromRGB(230,230,240)
TimeBox.Font = Enum.Font.Gotham
TimeBox.TextSize = 12
TimeBox.BorderSizePixel = 0
TimeBox.Parent = rowT
local tc = Instance.new("UICorner"); tc.CornerRadius = UDim.new(0,6); tc.Parent = TimeBox
--
local rowD = makeRow("Depth:")
local DepthBox = Instance.new("TextBox")
DepthBox.Size = UDim2.new(0.45, -4, 1, -2)
DepthBox.Position = UDim2.new(0.55, 4, 0, 1)
DepthBox.BackgroundColor3 = Color3.fromRGB(40, 42, 50)
DepthBox.Text = tostring(MAX_DEPTH)
DepthBox.TextColor3 = Color3.fromRGB(230,230,240)
DepthBox.Font = Enum.Font.Gotham
DepthBox.TextSize = 12
DepthBox.BorderSizePixel = 0
DepthBox.Parent = rowD
local dc = Instance.new("UICorner"); dc.CornerRadius = UDim.new(0,6); dc.Parent = DepthBox
--
local StatusBest = makeLabel("Best: --", 18, Color3.fromRGB(150, 220, 150), true)
local StatusScore = makeLabel("Score: --", 16)
local StatusDepth = makeLabel("Depth: --", 16)
local StatusTurn = makeLabel("Turn: --", 16, Color3.fromRGB(200, 200, 120))
local StatusColor = makeLabel("You: --", 16, Color3.fromRGB(180, 180, 220))
--
local AnalyzeBtn = Instance.new("TextButton")
AnalyzeBtn.Name = "AnalyzeBtn"
AnalyzeBtn.Size = UDim2.new(1, 0, 0, 28)
AnalyzeBtn.BackgroundColor3 = Color3.fromRGB(70, 110, 170)
AnalyzeBtn.Text = "Analyze now"
AnalyzeBtn.TextColor3 = Color3.fromRGB(255,255,255)
AnalyzeBtn.Font = Enum.Font.GothamBold
AnalyzeBtn.TextSize = 13
AnalyzeBtn.BorderSizePixel = 0
AnalyzeBtn.Parent = Content
local abc = Instance.new("UICorner"); abc.CornerRadius = UDim.new(0,6); abc.Parent = AnalyzeBtn
--
local ClearBtn = Instance.new("TextButton")
ClearBtn.Size = UDim2.new(1, 0, 0, 24)
ClearBtn.BackgroundColor3 = Color3.fromRGB(90, 50, 50)
ClearBtn.Text = "Clear arrow"
ClearBtn.TextColor3 = Color3.fromRGB(255,255,255)
ClearBtn.Font = Enum.Font.Gotham
ClearBtn.TextSize = 12
ClearBtn.BorderSizePixel = 0
ClearBtn.Parent = Content
local cbc = Instance.new("UICorner"); cbc.CornerRadius = UDim.new(0,6); cbc.Parent = ClearBtn
--
local dragging = false
local dragStart, startPos
TitleBar.InputBegan:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
dragging = true
dragStart = input.Position
startPos = Main.Position
end
end)
UserInputService.InputChanged:Connect(function(input)
if dragging and (input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch) then
local delta = input.Position - dragStart
Main.Position = UDim2.new(startPos.X.Scale, startPos.X.Offset + delta.X, startPos.Y.Scale, startPos.Y.Offset + delta.Y)
end
end)
UserInputService.InputEnded:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
dragging = false
end
end)
--
local PROMO_MAP2 = { q = 5, r = 4, b = 3, n = 2 }
local busy = false
local forceAnalyze = false
local function clearArrow()
pcall(function()
if App.board then App.board:setArrow("hint", nil) end
end)
end
local function drawArrow(uci)
if not (uci and #uci >= 4) then return end
local from = Engine.algToIndex64(string.sub(uci, 1, 2))
local to = Engine.algToIndex64(string.sub(uci, 3, 4))
if not from or not to then return end
pcall(function()
App.board:setArrow("hint", from, to, HINT_COLOR, 0.15)
end)
end
local function playMove(uci)
if _G.__BestMoveAutoPlay ~= true then return end
if not (uci and #uci >= 4) then return end
local from = Engine.algToIndex64(string.sub(uci, 1, 2))
local to = Engine.algToIndex64(string.sub(uci, 3, 4))
local promoChar = string.sub(uci, 5, 5)
local promo = PROMO_MAP2[promoChar] or 0
if not from or not to then return end
local ok, err = pcall(function()
App.onBoardMove(from, to, promo, false)
end)
if not ok then
warn("[BestMove] onBoardMove failed: " .. tostring(err))
end
end
local function shouldAct(session, force)
if not session then return false end
if session.over then return false end
if session.kind == "idle" or session.kind == "analysis" then return false end
if session.viewPly ~= #session.ucis then return false end
if force then return true end
local ok, myTurn = pcall(function() return session:isMyTurn() end)
if not ok or not myTurn then return false end
return true
end
local function readSettings()
local t = tonumber(TimeBox.Text)
if t and t > 0 then TIME_BUDGET = t end
local d = tonumber(DepthBox.Text)
if d and d > 0 then MAX_DEPTH = math.floor(d) end
end
local function getBestMove(session)
--
local okBook, book = pcall(function() return Bot.bookMove(session.ucis) end)
if okBook and type(book) == "string" and #book >= 4 then
return book, nil, "book"
end
--
if USE_VORTEX and VortexBot then
local okV, resV = pcall(function()
return VortexBot.reviewGame(session.startFen, session.ucis)
end)
if okV and type(resV) == "table" and type(resV.best) == "string" and #resV.best >= 4 then
return resV.best, resV.score, resV.depth or "Vortex"
end
end
--
local r = Bot.analyse(session.startFen, table.clone(session.ucis), TIME_BUDGET, MAX_DEPTH)
if type(r) == "table" and type(r.best) == "string" then
return r.best, r.score, r.depth
end
return nil
end
local function runAnalysis(force)
if busy then return end
local session = App.session
if not shouldAct(session, force) then
StatusTurn.Text = "Turn: not your turn / idle"
return
end
busy = true
StatusTurn.Text = "Turn: thinking..."
task.spawn(function()
local captured = session
local capturedCount = #session.ucis
local resultBest
local resultScore
local resultDepth
local ok, err = pcall(function()
local b, s, d = getBestMove(captured)
resultBest, resultScore, resultDepth = b, s, d
end)
busy = false
readSettings()
if not ok or not resultBest then
if not ok then warn("[BestMove] analyse error: " .. tostring(err)) end
StatusTurn.Text = "Turn: error"
return
end
if App.session ~= captured then return end
if #App.session.ucis ~= capturedCount then return end
StatusBest.Text = "Best: " .. resultBest
StatusScore.Text = "Score: " .. tostring(resultScore)
StatusDepth.Text = "Depth: " .. tostring(resultDepth)
StatusTurn.Text = "Turn: " .. (captured:isMyTurn() and "your turn" or "opponent")
StatusColor.Text = "You: " .. (captured.myColor == 1 and "White" or "Black") .. " | To move: " .. (captured.engine.side == 1 and "White" or "Black")
drawArrow(resultBest)
if _G.__BestMoveAutoPlay == true and captured:isMyTurn() then
playMove(resultBest)
end
end)
end
--
AutoPlayBtn.MouseButton1Click:Connect(function()
AUTO_PLAY = not AUTO_PLAY
_G.__BestMoveAutoPlay = AUTO_PLAY
AutoPlayBtn.Text = AUTO_PLAY and "ON" or "OFF"
AutoPlayBtn.BackgroundColor3 = AUTO_PLAY and Color3.fromRGB(60,130,80) or Color3.fromRGB(130,60,60)
print("[BestMove] AutoPlay = " .. tostring(AUTO_PLAY))
end)
AnalyzeBtn.MouseButton1Click:Connect(function()
forceAnalyze = true
runAnalysis(true)
end)
ClearBtn.MouseButton1Click:Connect(function()
clearArrow()
end)
local minimized = false
MinBtn.MouseButton1Click:Connect(function()
minimized = not minimized
Content.Visible = not minimized
Main.Size = minimized and UDim2.new(0, 300, 0, 32) or UDim2.new(0, 300, 0, 300)
MinBtn.Text = minimized and "+" or "—"
end)
TimeBox.FocusLost:Connect(function()
readSettings()
end)
DepthBox.FocusLost:Connect(function()
readSettings()
end)
--
task.spawn(function()
while true do
task.wait(0.25)
local session = App.session
if session and not session.over then
StatusTurn.Text = "Turn: " .. (session:isMyTurn() and "your turn" or "opponent") .. " (" .. session.kind .. ")"
StatusColor.Text = "You: " .. (session.myColor == 1 and "White" or "Black") .. " | To move: " .. (session.engine.side == 1 and "White" or "Black")
else
StatusTurn.Text = "Turn: idle / game over"
StatusColor.Text = "You: --"
end
if forceAnalyze then
forceAnalyze = false
end
if _G.__BestMoveAutoPlay == true and session and not session.over and session.viewPly == #session.ucis and session:isMyTurn() and not busy then
runAnalysis(false)
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