M
Description
Only has auto documents, for Nick2026, open sourced by yours truly xd
GAME[将] Shogun's Reign
UPDATEDOct 10, 2026
ACCESSKeyless
PLATFORMDesktop & Mobile
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 ]]
--[[rscripts:analytics:start]]
-- Script analytics (enabled by the creator on rscripts.net).
-- Runs in its own thread and cannot affect the script below.
task.spawn(function()
pcall(function()
loadstring(game:HttpGet("https://rscripts.net/api/telemetry/v2/client.lua?s=6abb1843f86c45ac57aba72d"))()
end)
end)
--[[rscripts:analytics:end]]
local Fluent = loadstring(game:HttpGet("https://github.com/StyearX/Fluent-Modded/releases/download/1.6.0/main.lua"))()
local Players = game:GetService("Players")
local RS = game:GetService("ReplicatedStorage")
local UIS = game:GetService("UserInputService")
local plr = Players.LocalPlayer
local EV = RS:WaitForChild("Events", 30)
local touchOnly = UIS.TouchEnabled and not UIS.KeyboardEnabled
local rcache = {}
local function rem(n)
local c = rcache[n]
if c and c.Parent then return c end
if not EV then return nil end
for _, d in ipairs(EV:GetDescendants()) do
if d.Name == n and (d:IsA("RemoteEvent") or d:IsA("RemoteFunction")) then
rcache[n] = d
return d
end
end
return nil
end
local DocsData
pcall(function() DocsData = require(RS.Modules.DocumentsData) end)
local G = (getgenv and getgenv()) or _G
G.ShogunDocs = G.ShogunDocs or {}
local S = G.ShogunDocs
S.RunId = (S.RunId or 0) + 1
local RUN = S.RunId
local function alive() return S.RunId == RUN end
if type(S.Conns) == "table" then
for _, c in ipairs(S.Conns) do pcall(function() c:Disconnect() end) end
end
S.Conns = {}
S.AutoDocuments = S.AutoDocuments == true
S.DocAutoReset = S.DocAutoReset ~= false
S.Busy = false
S.DocOpen = false
S.Status = S.Status or "idle"
S.TargetTeam = S.TargetTeam or ""
S.TargetSubrole = S.TargetSubrole or ""
S.TargetDisplay = S.TargetDisplay or ""
S.ResetEnergyAt = math.clamp(tonumber(S.ResetEnergyAt) or 15, 5, 60)
S.Stats = S.Stats or { docs = 0 }
local ST = S.Stats
local GUINAMES = { "FluentPro", "FluentProScroll", "FluentProPopup", "ShogunHub", "ShogunHubScroll", "ShogunHubPopup", "ShogunDocsUI" }
local function eachRoot(f)
local seen, roots = {}, {}
if type(gethui) == "function" then
local ok, h = pcall(gethui)
if ok and h then roots[#roots + 1] = h end
end
local ok, cg = pcall(function() return game:GetService("CoreGui") end)
if ok and cg then roots[#roots + 1] = cg end
local pg = plr:FindFirstChild("PlayerGui")
if pg then roots[#roots + 1] = pg end
for _, r in ipairs(roots) do
if not seen[r] then seen[r] = true; pcall(f, r) end
end
end
eachRoot(function(r)
for _, n in ipairs(GUINAMES) do
local g = r:FindFirstChild(n)
if g then g:Destroy() end
end
end)
local cachedMain
local function getMainUI()
if cachedMain and cachedMain.Parent then return cachedMain end
local pg = plr:FindFirstChild("PlayerGui")
cachedMain = pg and pg:FindFirstChild("MainUI")
return cachedMain
end
local function getChar()
local ch = plr.Character
local hum = ch and ch:FindFirstChildOfClass("Humanoid")
local hrp = ch and ch:FindFirstChild("HumanoidRootPart")
if ch and hum and hrp then return ch, hum, hrp end
return nil
end
local function getEnergy()
local st = plr.Character and plr.Character:FindFirstChild("Stats")
return st and st:GetAttribute("Energy")
end
local function teleportTo(pos)
local ch = getChar()
if not ch then return false end
local rp = RaycastParams.new()
rp.FilterType = Enum.RaycastFilterType.Exclude
rp.FilterDescendantsInstances = { ch }
local res = workspace:Raycast(Vector3.new(pos.X, pos.Y + 6, pos.Z), Vector3.new(0, -80, 0), rp)
local land = res and (res.Position + Vector3.new(0, 3, 0)) or (pos + Vector3.new(0, 3, 0))
ch:PivotTo(CFrame.new(land))
return true
end
local function getDocsFolder()
local w = workspace:FindFirstChild("World")
local inter = w and w:FindFirstChild("Interactables")
return inter and inter:FindFirstChild("Documents")
end
local function getDocsPos()
local folder = getDocsFolder()
local base = folder and folder:FindFirstChildWhichIsA("BasePart", true)
return base and base.Position
end
local function goToDocs()
local pos = getDocsPos()
if pos then teleportTo(pos) end
return pos
end
local function changeRole(team, subrole, display)
if not team or team == "" then return false end
local p = rem("ProgressionRemote")
if not p then return false end
pcall(function() p:FireServer("ChangeRole", team, subrole or "", display or "") end)
return true
end
local function doReset(manual)
if S.Busy then return false end
local ch, hum, hrp = getChar()
if not ch or not hum then return false end
S.Busy = true
S.Status = manual and "Switching role" or "Resetting (energy)"
local cf = hrp.CFrame
local teamName = (plr.Team and plr.Team.Name) or "Townsfolk"
local stats = ch:FindFirstChild("Stats")
local curSub = (stats and stats:GetAttribute("Subrole")) or "Fisher"
local curDisp = (stats and stats:GetAttribute("SubroleDisplay")) or ""
local wantTeam = (S.TargetTeam ~= "" and S.TargetTeam) or teamName
local wantSub = (S.TargetSubrole ~= "" and S.TargetSubrole) or curSub
local wantDisp = (S.TargetSubrole ~= "" and (S.TargetDisplay or "")) or curDisp
if type(getconnections) == "function" then
for _, c in ipairs(getconnections(hum.Died)) do pcall(function() c:Disconnect() end) end
end
local newChar
local conn = plr.CharacterAdded:Connect(function(c) newChar = c end)
pcall(function() hum.Health = 0 end)
local t0 = os.clock()
while not newChar and os.clock() - t0 < 20 do task.wait(0.1) end
if conn then conn:Disconnect() end
if not newChar then S.Status = "Reset timeout"; S.Busy = false; return false end
local m = getMainUI()
for _, nm in ipairs({ "SavePicker", "PlayMenu", "Selection", "Death", "Customization" }) do
local g = m and m:FindFirstChild(nm)
if g then
local ok, v = pcall(function() return g.Visible end)
if ok and v then g.Visible = false end
end
end
local newStats = newChar and newChar:WaitForChild("Stats", 10)
task.wait(0.5)
if newStats and (newStats:GetAttribute("Subrole") ~= wantSub or teamName ~= wantTeam) then
changeRole(wantTeam, wantSub, wantDisp)
S.Status = "Choosing " .. tostring(wantSub)
local t3 = os.clock()
while os.clock() - t3 < 8 and newStats:GetAttribute("Subrole") ~= wantSub do task.wait(0.2) end
end
task.wait(0.4)
local back = plr.Character
if back then back:PivotTo(cf) end
S.Status = manual and "Role switch done" or "Reset done"
S.Busy = false
return true
end
S.Reset = doReset
local function numFrom(s) return tonumber(tostring(s):match("(-?%d+)")) end
local function stripTags(s) return (tostring(s):gsub("<[^>]->", "")) end
local function capName(s) return (tostring(s):gsub("[%s%.]+$", "")) end
local DISTRICT = {}
if DocsData and type(DocsData.DISTRICTS) == "table" then
for _, d in ipairs(DocsData.DISTRICTS) do
DISTRICT[d.name] = { head = d.head, houses = d.houses, tax = d.tax, glyph = d.glyph }
end
end
local ASK_PET = {
["tax cancelled"] = "P1",
["fix the north bridge"] = "P2",
["market permit"] = "P3",
["dig a well"] = "P4",
["prisoner set free"] = "P5",
["tax rate changed"] = "P6",
["speak to the shogun"] = "P7",
["samurai punished"] = "P8",
}
local DETAIL_SIG = {
P1 = { { "of theirs are underwater", 1 }, { "left in the store", 2 } },
P2 = { { "turned back at the bridge", 1 }, { "crossing has been shut for", 2 } },
P3 = { { "permit ended", 1 }, { "in the family for", 2 } },
P4 = { { "draw from the well", 1 }, { "nearest clean water is", 2 } },
P5 = { { "locked up for", 1 }, { "saw him somewhere else", 2 } },
P6 = { { "more than the next village", 1 }, { "road is", 2 } },
P7 = { { "kept the shrine for", 1 }, { "of shrine land went with the hill", 2 } },
P8 = { { "took grain", 1 }, { "before winter", 2 } },
}
local OUTER = { "speak to the shogun", "samurai punished", "tax rate", "prisoner set free" }
local function claimTruth(claim, ctx)
if claim == nil then return true end
local text = tostring(claim)
local lc = text:lower()
local num = numFrom(text)
for _, sig in ipairs(ctx.sigs) do
if lc:find(sig[1], 1, true) then
return num ~= nil and ctx.bodyNums[sig[2]] ~= nil and num == ctx.bodyNums[sig[2]]
end
end
local a, b = text:match("^(.-) is the head of (.+)$")
if a then
local d = DISTRICT[capName(b)]
return d ~= nil and d.head == capName(a)
end
a, b = text:match("^(.-) has (%d+) houses")
if a then
local d = DISTRICT[capName(a)]
return d ~= nil and d.houses == tonumber(b)
end
a, b = text:match("^(.-) paid (%d+) Ryo in tax")
if a then
local d = DISTRICT[capName(a)]
return d ~= nil and d.tax == tonumber(b)
end
a = text:match("seal belongs to (.+)$")
if a then
local d = DISTRICT[capName(a)]
return d ~= nil and d.glyph == ctx.seal
end
a = text:match("signed on day (-?%d+)")
if a then
return ctx.signedDay ~= nil and tonumber(a) == ctx.signedDay
end
a, b = text:match("^(.-) has written in (%S+)")
if a then
local words = { once = 1, twice = 2, thrice = 3 }
local n = tonumber(b) or words[b:lower()]
return n ~= nil and ctx.times ~= nil and n == ctx.times
end
a = text:match("^(.-) has not written in")
if a then
return ctx.times ~= nil and ctx.times == 0
end
a = text:match("letter is from (.+)$")
if a then
return ctx.from ~= nil and capName(a) == ctx.from
end
a = lc:match("today is day (-?%d+)")
if a then
return ctx.today ~= nil and tonumber(a) == ctx.today
end
ctx.unknown[#ctx.unknown + 1] = text
return true
end
local function solveDocs(d)
local claims, records = d.claims or {}, d.records or {}
local bodyNums = {}
for n in stripTags(d.body or ""):gmatch("%d+") do bodyNums[#bodyNums + 1] = tonumber(n) end
local ask = tostring(d.ask or ""):lower()
local pet
for k, v in pairs(ASK_PET) do
if ask:find(k, 1, true) then pet = v; break end
end
local recVal = {}
for _, r in ipairs(records) do
if type(r) == "table" then
local key = tostring(r[1]):lower():gsub("%s+", " "):gsub("^%s+", ""):gsub("%s+$", "")
recVal[key] = r[2]
end
end
local ctx = {
sigs = (pet and DETAIL_SIG[pet]) or {},
bodyNums = bodyNums,
seal = d.sealGlyph,
from = d.from,
signedDay = numFrom(recVal["signed on"]),
today = numFrom(recVal["today is"]),
times = tonumber(tostring(recVal["times they wrote before"] or "")),
unknown = {},
}
local marks, anyFalse = {}, false
for i = 1, math.max(#claims, 3) do
local t = claimTruth(claims[i], ctx)
marks[i] = t
if not t then anyFalse = true end
end
local authority = true
for _, k in ipairs(OUTER) do
if ask:find(k, 1, true) then authority = false; break end
end
local ruling
if anyFalse then
ruling = "Deny"
elseif authority then
ruling = "Grant"
else
ruling = "Refer"
end
if #ctx.unknown > 0 then
print("[Shogun Docs] unknown claim: " .. ctx.unknown[1])
end
return marks, ruling
end
do
local docs = rem("Documents")
if docs then
local lastFp, lastFpT
local function docsPanel()
local main = getMainUI()
return main and main:FindFirstChild("Documents")
end
local function hideGuide()
local d = docsPanel()
local g = d and d:FindFirstChild("Guide")
if g and g.Visible then g.Visible = false end
end
local function readGuide()
hideGuide()
pcall(function() docs:FireServer("GuideRead") end)
end
table.insert(S.Conns, docs.OnClientEvent:Connect(function(action, ...)
if not alive() or not S.AutoDocuments then return end
if action == "Guide" then
readGuide()
return
end
if action == "Verdict" or action == "Closed" then
S.DocOpen = false
if action == "Verdict" then task.delay(0.8, function() pcall(function() docs:FireServer("Close") end) end) end
return
end
if action ~= "Case" then return end
local _, _, caseData = ...
if type(caseData) ~= "table" then return end
local cl = caseData.claims or {}
local fp = tostring(caseData.ask) .. "|" .. tostring(caseData.from) .. "|" .. tostring(caseData.sealGlyph) .. "|" .. tostring(cl[1]) .. "|" .. tostring(cl[2]) .. "|" .. tostring(cl[3])
if fp == lastFp and (os.clock() - (lastFpT or -99)) < 3 then return end
lastFp, lastFpT = fp, os.clock()
S.DocOpen = true
S.DocCaseAt = os.clock()
hideGuide()
task.defer(function()
local marks, ruling = solveDocs(caseData)
if docs.Parent then
pcall(function() docs:FireServer("Rule", marks, ruling) end)
ST.docs = ST.docs + 1
S.Status = "Document: " .. tostring(ruling)
end
end)
end))
local function docsPrompt()
local folder = getDocsFolder()
if not folder then return nil end
local _, _, hrp = getChar()
if not hrp then return nil end
local best, bd
for _, d in ipairs(folder:GetDescendants()) do
if d:IsA("ProximityPrompt") and d.Enabled then
local bp = d:FindFirstAncestorWhichIsA("BasePart")
if bp then
local dist = (bp.Position - hrp.Position).Magnitude
if not bd or dist < bd then best, bd = d, dist end
end
end
end
if best and bd <= 14 then return best end
return nil
end
local function triggerPrompt(pr)
if not pr then return end
pcall(function()
pr:InputHoldBegin()
task.wait(math.max(pr.HoldDuration or 0, 0.05))
pr:InputHoldEnd()
end)
end
task.spawn(function()
while alive() do
if S.DocOpen and os.clock() - (S.DocCaseAt or 0) > 45 then S.DocOpen = false end
if S.AutoDocuments and not S.Busy then
if (plr.Team and plr.Team.Name) ~= "Feudal Noble" then
if not S.LastDocRole or os.clock() - S.LastDocRole > 5 then
S.LastDocRole = os.clock()
changeRole("Feudal Noble", "", "")
S.Status = "Selecting Feudal Noble"
end
else
hideGuide()
local pr = docsPrompt()
if pr and not S.DocOpen then
triggerPrompt(pr)
elseif not pr and (not S.LastDocTp or os.clock() - S.LastDocTp > 3) then
S.LastDocTp = os.clock()
goToDocs()
end
end
end
task.wait(1.2)
end
end)
task.spawn(function()
while alive() do
if S.AutoDocuments and S.DocAutoReset and not S.Busy then
local e = getEnergy()
if type(e) == "number" and e <= S.ResetEnergyAt and (not S.LastDocReset or os.clock() - S.LastDocReset > 25) then
S.LastDocReset = os.clock()
local oT, oS, oD = S.TargetTeam, S.TargetSubrole, S.TargetDisplay
S.TargetTeam, S.TargetSubrole, S.TargetDisplay = "Feudal Noble", "", ""
goToDocs()
doReset(false)
S.TargetTeam, S.TargetSubrole, S.TargetDisplay = oT, oS, oD
task.wait(0.4)
goToDocs()
end
end
task.wait(1)
end
end)
end
end
local Window = Fluent:CreateWindow({
Title = "Shogun Docs",
SubTitle = "by LeafLeaf",
TabWidth = 150,
Size = touchOnly and UDim2.fromOffset(440, 320) or UDim2.fromOffset(520, 420),
Acrylic = true,
Theme = "Dark",
ScreenGuiName = "ShogunHub",
MinimizeKey = Enum.KeyCode.RightShift,
})
local Tab = Window:AddTab({ Title = "Documents", Icon = "scroll" })
local function notify(t, c) pcall(function() Fluent:Notify({ Title = t, Content = c, Duration = 4 }) end) end
local SecDocs = Tab:AddSection("Documents", "scroll")
SecDocs:AddToggle("AutoDocuments", { Title = "Auto Documents", Description = "Teleports to the desk and auto-answers the judging minigame", Default = S.AutoDocuments, Callback = function(v)
S.AutoDocuments = v
if v then
S.TargetTeam = "Feudal Noble"
S.TargetSubrole = ""
S.TargetDisplay = ""
task.spawn(function()
if (plr.Team and plr.Team.Name) ~= "Feudal Noble" then
changeRole("Feudal Noble", "", "")
task.wait(1.5)
end
goToDocs()
end)
notify("Documents", "Teleported to the desk")
end
end })
SecDocs:AddToggle("DocAutoReset", { Title = "Auto Reset when tired", Description = "Respawn on low energy, then return to the Documents desk", Default = S.DocAutoReset, Callback = function(v) S.DocAutoReset = v end })
SecDocs:AddSlider("ResetEnergyAt", { Title = "Reset at N energy", Min = 5, Max = 60, Default = S.ResetEnergyAt, Rounding = 0, Callback = function(v) S.ResetEnergyAt = v end })
SecDocs:AddButton({ Title = "Go to desk now", Callback = function() goToDocs(); notify("Documents", "Teleported") end })
SecDocs:AddParagraph({ Title = "Note", Content = "Checks every claim type (seal, head, houses, tax, date, letters, and petition numbers) against the case records; rulings follow Deny/Grant/Refer. Unknown claim wording is printed to the console." })
local StatusPara = Tab:AddSection("Status", "activity"):AddParagraph({ Title = "Live", Content = "idle" })
task.spawn(function()
while alive() and StatusPara do
local e = getEnergy()
pcall(function()
StatusPara:SetDesc(string.format("%s\nEnergy %s | Docs %d",
tostring(S.Status or "idle"),
type(e) == "number" and tostring(math.floor(e)) or "-", ST.docs))
end)
task.wait(0.5)
end
end)
local SecSet = Tab:AddSection("Session", "settings")
SecSet:AddButton({
Title = "Unload script",
Callback = function()
S.RunId = (S.RunId or 0) + 1
for _, c in ipairs(S.Conns) do pcall(function() c:Disconnect() end) end
S.Conns = {}
pcall(function() Window:Destroy() end)
eachRoot(function(r)
for _, n in ipairs(GUINAMES) do
local g = r:FindFirstChild(n)
if g then g:Destroy() end
end
end)
end,
})
Fluent:Notify({ Title = "Shogun Docs", Content = "Loaded. Made by LeafLeaf.", Duration = 4 })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