Test debug console functionality and other corescript formatting improvements

This commit is contained in:
Lewin Kelly 2024-03-23 23:34:15 +00:00
parent fd5cc15ff6
commit 615fbc465c
4 changed files with 168 additions and 130 deletions

54
Modules/DebugConsole.luau Normal file
View File

@ -0,0 +1,54 @@
local Players = game:GetService "Players"
local New = (require "../Modules/New").New
return function(parent: Instance)
local username = Players.LocalPlayer.Name
if username ~= "Heliodex" then -- Don't show the debug console for anyone but me
return
end
local logEvent = New "BindableEvent" {
Name = "Log",
Parent = parent,
}
local screen = New "ScreenGui" {
Name = "Debug console",
Parent = parent,
}
local frame = New "Frame" {
Name = "Frame",
BackgroundTransparency = 1,
Position = UDim2.new(0, 0, 0, 0),
Size = UDim2.new(0.5, 0, 1, 0),
Parent = screen
New "TextBox" {
Name = "Input",
BackgroundColor3 = Color3.new(0, 0, 0),
BackgroundTransparency = 0.5,
BorderSizePixel = 0,
Position = UDim2.new(0, 0, 1, -30),
Size = UDim2.new(1, 0, 0, 30),
Font = Enum.Font.SourceSans,
FontSize = Enum.FontSize.Size14,
TextColor3 = Color3.new(1, 1, 1),
TextXAlignment = Enum.TextXAlignment.Left,
},
}
local console = New "TextBox" {
Name = "Console",
BackgroundColor3 = Color3.new(0, 0, 0),
BackgroundTransparency = 0.5,
BorderSizePixel = 0,
Position = UDim2.new(0, 0, 1, -30),
Size = UDim2.new(1, 0, 0, 30),
Font = Enum.Font.SourceSans,
FontSize = Enum.FontSize.Size14,
TextColor3 = Color3.new(1, 1, 1),
TextXAlignment = Enum.TextXAlignment.Left,
Parent = frame
}
end

View File

@ -5,6 +5,8 @@ print "[Mercury]: Loaded corescript 37801172"
local ScriptContext = game:GetService "ScriptContext" local ScriptContext = game:GetService "ScriptContext"
local CoreGui = game:GetService "CoreGui" local CoreGui = game:GetService "CoreGui"
require "../Modules/DebugConsole"(CoreGui)
-- Creates all neccessary scripts for the gui on initial load, everything except build tools -- Creates all neccessary scripts for the gui on initial load, everything except build tools
-- Please note that these are loaded in a specific order to diminish errors/perceived load time by user -- Please note that these are loaded in a specific order to diminish errors/perceived load time by user

View File

@ -59,7 +59,7 @@ local function getScreenGuiAncestor(instance)
return localInstance return localInstance
end end
local function Colour3(r, g, b) local function Colour3(r: number, g: number, b: number)
return Color3.new(r / 255, g / 255, b / 255) return Color3.new(r / 255, g / 255, b / 255)
end end

View File

@ -56,7 +56,7 @@ local function MakeBackgroundGuiObj(imgName)
} }
end end
--[[ turns 255 integer color value to a color3 --]] --[[ turns 255 integer color value to a color3 --]]
local function Color3I(r, g, b) local function Colour3(r: number, g: number, b: number)
return Color3.new(r / 255, g / 255, b / 255) return Color3.new(r / 255, g / 255, b / 255)
end end
@ -102,66 +102,15 @@ local function getFriendStatusIcon(friendStatus)
end end
end end
local HeaderFrame
--[[
Utility function to create buttons for the popup menus
@Args:
nparent what to parent this button to
ntext text to put on this button
index number index of this entry in menu
last is this the last element of the popup menu
@Return: a popup menu button
--]]
local function MakePopupButton(nparent, ntext, index, last)
local tobj = New "ImageButton" {
Name = "ReportButton",
BackgroundTransparency = 1,
Position = UDim2.new(0, 0, 1 * index, 0),
Size = UDim2.new(1, 0, 1, 0),
ZIndex = 7,
New "TextLabel" {
Name = "ButtonText",
BackgroundTransparency = 1,
Position = UDim2.new(0.07, 0, 0.07, 0),
Size = UDim2.new(0.86, 0, 0.86, 0),
Parent = HeaderFrame,
Font = "ArialBold",
Text = ntext,
FontSize = "Size14",
TextScaled = true,
TextColor3 = Color3.new(1, 1, 1),
TextStrokeTransparency = 1,
ZIndex = 7,
},
Parent = nparent,
}
if index == 0 then
tobj.Image = "http://banland.xyz/asset?id=97108784"
elseif last then
if index % 2 == 1 then
tobj.Image = "http://banland.xyz/asset?id="
.. Images.LightPopupBottom
else
tobj.Image = "http://banland.xyz/asset?id="
.. Images.DarkPopupBottom
end
else
if index % 2 == 1 then
tobj.Image = "http://banland.xyz/asset?id=97112126"
else
tobj.Image = "http://banland.xyz/asset?id=97109338"
end
end
return tobj
end
--------------------------- ---------------------------
-- Workspace Objects -- Workspace Objects
--------------------------- ---------------------------
-- might want to move all this to an init function, wait for localplayer elsewhere -- might want to move all this to an init function, wait for localplayer elsewhere
local ContentProvider = game:GetService "ContentProvider"
local PersonalServerService = game:GetService "PersonalServerService"
local Players = game:GetService "Players" local Players = game:GetService "Players"
-- make sure this doesn't run on the server(it will if you dont do this) -- make sure this doesn't run on the server(it will if you dont do this)
while not Players.LocalPlayer do while not Players.LocalPlayer do
Players.Changed:wait() Players.Changed:wait()
@ -184,7 +133,7 @@ local MainFrame = New "Frame" {
Parent = ScreenGui, Parent = ScreenGui,
} }
--frame used for expanding leaderstats when frame is 'focused' -- frame used for expanding leaderstats when frame is "focussed"
local FocusFrame = New "Frame" { local FocusFrame = New "Frame" {
Name = "FocusFrame", Name = "FocusFrame",
Position = UDim2.new(0, 0, 0, 0), Position = UDim2.new(0, 0, 0, 0),
@ -195,7 +144,7 @@ local FocusFrame = New "Frame" {
} }
-- HEADER -- HEADER
HeaderFrame = New "Frame" { local HeaderFrame = New "Frame" {
Name = "Header", Name = "Header",
BackgroundTransparency = 1, BackgroundTransparency = 1,
Position = UDim2.new(0, 0, 0, 0), Position = UDim2.new(0, 0, 0, 0),
@ -415,9 +364,15 @@ local MiddleTemplate = New "Frame" {
TextYAlignment = "Center", TextYAlignment = "Center",
ZIndex = 3, ZIndex = 3,
}, },
--Create'IntValue'{Name = 'ID'}, -- New "IntValue" {
--Create'ObjectValue'{Name = 'Player'}, -- Name = "ID",
--Create'IntValue'{Name = 'Score'}, -- },
-- New "ObjectValue" {
-- Name = "Player",
-- },
-- New "IntValue" {
-- Name = "Score",
-- },
ZIndex = 3, ZIndex = 3,
} }
local MiddleBGTemplate = New "Frame" { local MiddleBGTemplate = New "Frame" {
@ -437,8 +392,8 @@ local ReportAbuseShield = New "TextButton" {
Active = true, Active = true,
Visible = true, Visible = true,
Size = UDim2.new(1, 0, 1, 0), Size = UDim2.new(1, 0, 1, 0),
BackgroundColor3 = Color3I(51, 51, 51), BackgroundColor3 = Colour3(51, 51, 51),
BorderColor3 = Color3I(27, 42, 53), BorderColor3 = Colour3(27, 42, 53),
BackgroundTransparency = 1, BackgroundTransparency = 1,
} }
@ -460,15 +415,15 @@ local AbuseSettingsFrame = New "Frame" {
New "TextLabel" { New "TextLabel" {
Name = "Title", Name = "Title",
Text = "Report Abuse", Text = "Report Abuse",
TextColor3 = Color3I(221, 221, 221), TextColor3 = Colour3(221, 221, 221),
Position = UDim2.new(0.5, 0, 0, 30), Position = UDim2.new(0.5, 0, 0, 30),
Font = Enum.Font.ArialBold, Font = Enum.Font.ArialBold,
FontSize = Enum.FontSize.Size36, FontSize = Enum.FontSize.Size36,
}, },
New "TextLabel" { New "TextLabel" {
Name = "Description", Name = "Description",
Text = "This will send a complete report to a moderator. The moderator will review the chat log and take appropriate action.", Text = "This will send a complete report to a moderator. The moderator will review the chat log and take appropriate action.",
TextColor3 = Color3I(221, 221, 221), TextColor3 = Colour3(221, 221, 221),
Position = UDim2.new(0.01, 0, 0, 55), Position = UDim2.new(0.01, 0, 0, 55),
Size = UDim2.new(0.99, 0, 0, 40), Size = UDim2.new(0.99, 0, 0, 40),
BackgroundTransparency = 1, BackgroundTransparency = 1,
@ -486,7 +441,7 @@ local AbuseSettingsFrame = New "Frame" {
FontSize = Enum.FontSize.Size18, FontSize = Enum.FontSize.Size18,
Position = UDim2.new(0.025, 0, 0, 140), Position = UDim2.new(0.025, 0, 0, 140),
Size = UDim2.new(0.4, 0, 0, 36), Size = UDim2.new(0.4, 0, 0, 36),
TextColor3 = Color3I(255, 255, 255), TextColor3 = Colour3(255, 255, 255),
TextXAlignment = Enum.TextXAlignment.Left, TextXAlignment = Enum.TextXAlignment.Left,
}, },
New "TextLabel" { New "TextLabel" {
@ -496,7 +451,7 @@ local AbuseSettingsFrame = New "Frame" {
FontSize = Enum.FontSize.Size18, FontSize = Enum.FontSize.Size18,
Position = UDim2.new(0.025, 0, 0, 180), Position = UDim2.new(0.025, 0, 0, 180),
Size = UDim2.new(0.95, 0, 0, 36), Size = UDim2.new(0.95, 0, 0, 36),
TextColor3 = Color3I(255, 255, 255), TextColor3 = Colour3(255, 255, 255),
TextXAlignment = Enum.TextXAlignment.Left, TextXAlignment = Enum.TextXAlignment.Left,
BackgroundTransparency = 1, BackgroundTransparency = 1,
}, },
@ -508,7 +463,7 @@ local AbuseSettingsFrame = New "Frame" {
FontSize = Enum.FontSize.Size18, FontSize = Enum.FontSize.Size18,
Position = UDim2.new(0.025, 0, 0, 100), Position = UDim2.new(0.025, 0, 0, 100),
Size = UDim2.new(0.95, 0, 0, 36), Size = UDim2.new(0.95, 0, 0, 36),
TextColor3 = Color3I(255, 255, 255), TextColor3 = Colour3(255, 255, 255),
TextXAlignment = Enum.TextXAlignment.Left, TextXAlignment = Enum.TextXAlignment.Left,
}, },
@ -523,7 +478,7 @@ local AbusePlayerLabel = New "TextLabel" {
FontSize = Enum.FontSize.Size18, FontSize = Enum.FontSize.Size18,
Position = UDim2.new(0.025, 0, 0, 100), Position = UDim2.new(0.025, 0, 0, 100),
Size = UDim2.new(0.95, 0, 0, 36), Size = UDim2.new(0.95, 0, 0, 36),
TextColor3 = Color3I(255, 255, 255), TextColor3 = Colour3(255, 255, 255),
TextXAlignment = Enum.TextXAlignment.Right, TextXAlignment = Enum.TextXAlignment.Right,
Parent = AbuseSettingsFrame, Parent = AbuseSettingsFrame,
} }
@ -553,7 +508,7 @@ local AbuseDescriptionWrapper = New "Frame" {
Name = "AbuseDescriptionWrapper", Name = "AbuseDescriptionWrapper",
Position = UDim2.new(0.025, 0, 0, 220), Position = UDim2.new(0.025, 0, 0, 220),
Size = UDim2.new(0.95, 0, 1, -310), Size = UDim2.new(0.95, 0, 1, -310),
BackgroundColor3 = Color3I(0, 0, 0), BackgroundColor3 = Colour3(0, 0, 0),
BorderSizePixel = 0, BorderSizePixel = 0,
Parent = AbuseSettingsFrame, Parent = AbuseSettingsFrame,
} }
@ -568,11 +523,11 @@ local OriginalAbuseDescriptionBox = New "TextBox" {
FontSize = Enum.FontSize.Size18, FontSize = Enum.FontSize.Size18,
Position = UDim2.new(0, 3, 0, 3), Position = UDim2.new(0, 3, 0, 3),
Size = UDim2.new(1, -6, 1, -6), Size = UDim2.new(1, -6, 1, -6),
TextColor3 = Color3I(255, 255, 255), TextColor3 = Colour3(255, 255, 255),
TextXAlignment = Enum.TextXAlignment.Left, TextXAlignment = Enum.TextXAlignment.Left,
TextYAlignment = Enum.TextYAlignment.Top, TextYAlignment = Enum.TextYAlignment.Top,
TextWrap = true, TextWrap = true,
BackgroundColor3 = Color3I(0, 0, 0), BackgroundColor3 = Colour3(0, 0, 0),
BorderSizePixel = 0, BorderSizePixel = 0,
} }
@ -602,7 +557,7 @@ local CalmingAbuseBox = New "Frame" {
TextScaled = true, TextScaled = true,
BackgroundTransparency = 1, BackgroundTransparency = 1,
TextColor3 = Color3.new(1, 1, 1), TextColor3 = Color3.new(1, 1, 1),
Text = "Our moderators will review the chat logs and determine what happened. The other user is probably just trying to make you mad.\n\nIf anyone used swear words, inappropriate language, or threatened you in real life, please report them for Bad Words or Threats", Text = "Our moderators will review the chat logs and determine what happened. The other user is probably just trying to make you mad.\n\nIf anyone used swear words, inappropriate language, or threatened you in real life, please report them for Bad Words or Threats",
TextWrapped = true, TextWrapped = true,
TextYAlignment = Enum.TextYAlignment.Top, TextYAlignment = Enum.TextYAlignment.Top,
FontSize = Enum.FontSize.Size24, FontSize = Enum.FontSize.Size24,
@ -659,19 +614,20 @@ local NormalAbuseBox = New "Frame" {
}, },
} }
local BigButton = Instance.new "ImageButton" local BigButton = New "ImageButton" {
BigButton.Size = UDim2.new(1, 0, 1, 0) Size = UDim2.new(1, 0, 1, 0),
BigButton.BackgroundTransparency = 1 BackgroundTransparency = 1,
BigButton.ZIndex = 8 ZIndex = 8,
BigButton.Visible = false Visible = false,
--BigButton.Active=false -- Active = false,
BigButton.Parent = ScreenGui Parent = ScreenGui,
}
local debugFrame = New "Frame" { local debugFrame = New "Frame" {
Name = "debugframe", Name = "debugframe",
--Position = UDim2.new(0, 0, 0, 0), -- Position = UDim2.new(0, 0, 0, 0),
--Size = UDim2.new(0, 150, 0, 800),--0.99000001 -- Size = UDim2.new(0, 150, 0, 800),--0.99000001
--BackgroundTransparency = 1, -- BackgroundTransparency = 1,
BackgroundTransparency = 1, BackgroundTransparency = 1,
Position = UDim2.new(0.25, 0, 0.300000012, 0), Position = UDim2.new(0.25, 0, 0.300000012, 0),
Size = UDim2.new(0.5, 0, 0.370000005, 0), Size = UDim2.new(0.5, 0, 0.370000005, 0),
@ -728,9 +684,7 @@ local RbxGui = assert(LoadLibrary "RbxGui")
local DefaultEntriesOnScreen = 8 local DefaultEntriesOnScreen = 8
for _, i in pairs(Images) do for _, i in pairs(Images) do
Game:GetService("ContentProvider"):Preload( ContentProvider:Preload("http://banland.xyz/asset?id=" .. i)
`http://banland.xyz/asset?id={i}`
)
end end
-- ordered array of 'score data', each entry has: -- ordered array of 'score data', each entry has:
@ -755,7 +709,7 @@ local PlayerFrames = {}
-- AutoHide (bool saying whether it should be hidden) -- AutoHide (bool saying whether it should be hidden)
-- IsHidden (bool) -- IsHidden (bool)
-- ID (int to prevent flipping out of leaderboard, fun times) -- ID (int to prevent flipping out of leaderboard, fun times)
local TeamFrames = {} local TeamFrames: { any } = {}
-- one special entry from teamFrames, for unaffiliated players, only shown if players non - empty -- one special entry from teamFrames, for unaffiliated players, only shown if players non - empty
local NeutralTeam local NeutralTeam
@ -767,9 +721,9 @@ local LastClick = 0
local ButtonCooldown = 0.25 local ButtonCooldown = 0.25
local OnIos = false local OnIos = false
pcall(function() -- pcall(function()
OnIos = Game:GetService("UserInputService").TouchEnabled -- OnIos = Game:GetService("UserInputService").TouchEnabled
end) -- end)
-- you get 200 of x screen space per stat added, start width 16% -- you get 200 of x screen space per stat added, start width 16%
local BaseScreenXSize = 150 local BaseScreenXSize = 150
@ -798,7 +752,7 @@ local InPopupWaitForClick = false
local PlayerChangedLock = false local PlayerChangedLock = false
local NeutralTeamLock = false local NeutralTeamLock = false
local ScrollWheelConnections = {} local ScrollWheelConnections: { RBXScriptConnection }? = {}
local DefaultListSize = 8 local DefaultListSize = 8
if not OnIos then if not OnIos then
@ -839,27 +793,12 @@ local PrivilegeLevel = {
------------------------------- -------------------------------
-- Static Functions -- Static Functions
------------------------------- -------------------------------
-- function GetTotalEntries()
-- return math.min(#MiddleFrameBackgrounds, DefaultEntriesOnScreen)
-- end
-- function GetEntryListLength()
-- local numEnts = #PlayerFrames + #TeamFrames
-- if NeutralTeam then
-- numEnts += 1
-- end
-- return numEnts
-- end
local function AreAllEntriesOnScreen() local function AreAllEntriesOnScreen()
return #MiddleFrameBackgrounds * MiddleTemplate.Size.Y.Scale return #MiddleFrameBackgrounds * MiddleTemplate.Size.Y.Scale
<= 1 + DefaultBottomClipPos <= 1 + DefaultBottomClipPos
end end
-- function GetLengthOfVisbleScroll()
-- return 1 + DefaultBottomClipPos
-- end
local function GetMaxScroll() local function GetMaxScroll()
return DefaultBottomClipPos * -1 return DefaultBottomClipPos * -1
end end
@ -889,7 +828,7 @@ end
enda alpha to end tweening on enda alpha to end tweening on
length how many seconds to spend tweening length how many seconds to spend tweening
--]] --]]
local function TweenProperty(obj, propName, inita, enda, length) local function TweenProperty(obj, propName, inita: number, enda: number, length)
local startTime = tick() local startTime = tick()
while tick() - startTime < length do while tick() - startTime < length do
obj[propName] = ((enda - inita) * ((tick() - startTime) / length)) obj[propName] = ((enda - inita) * ((tick() - startTime) / length))
@ -947,7 +886,7 @@ end
--Personal Server Handling --Personal Server Handling
--------------------------- ---------------------------
--[[ --[[
returns privlage level based on integer rank returns privilege level based on integer rank
Note: these privilege levels seem completely arbitrary, but no documentation exists Note: these privilege levels seem completely arbitrary, but no documentation exists
this is all from the old player list, really weird this is all from the old player list, really weird
@Args: @Args:
@ -978,10 +917,10 @@ end
--]] --]]
local function SetPrivilegeRank(player, nrank) local function SetPrivilegeRank(player, nrank)
while player.PersonalServerRank < nrank do while player.PersonalServerRank < nrank do
game:GetService("PersonalServerService"):Promote(player) PersonalServerService:Promote(player)
end end
while player.PersonalServerRank > nrank do while player.PersonalServerRank > nrank do
game:GetService("PersonalServerService"):Demote(player) PersonalServerService:Demote(player)
end end
end end
@ -1139,8 +1078,7 @@ local function InitReportAbuse()
end end
end end
AbuseDropDown, _ = AbuseDropDown = RbxGui.CreateDropDownMenu(Abuses, UpdateAbuseFunction, true)
RbxGui.CreateDropDownMenu(Abuses, UpdateAbuseFunction, true)
AbuseDropDown.Name = "AbuseComboBox" AbuseDropDown.Name = "AbuseComboBox"
AbuseDropDown.Position = UDim2.new(0.425, 0, 0, 142) AbuseDropDown.Position = UDim2.new(0.425, 0, 0, 142)
AbuseDropDown.Size = UDim2.new(0.55, 0, 0, 32) AbuseDropDown.Size = UDim2.new(0.55, 0, 0, 32)
@ -1553,16 +1491,13 @@ local function UpdateMaximize()
end end
end end
local function GetScoreValue(score) local function GetScoreValue(score: ValueBase): number
if if
score:IsA "DoubleConstrainedValue" or score:IsA "IntConstrainedValue" score:IsA "DoubleConstrainedValue" or score:IsA "IntConstrainedValue"
then then
return score.ConstrainedValue return score.ConstrainedValue
elseif score:IsA "BoolValue" then elseif score:IsA "BoolValue" then
if score.Value then return score.Value and 1 or 0
return 1
end
return 0
end end
return score.Value return score.Value
end end
@ -2038,8 +1973,8 @@ end
-- removes and closes all leaderboard stuffs -- removes and closes all leaderboard stuffs
local function BlowThisPopsicleStand() local function BlowThisPopsicleStand()
--ScreenGui:Destroy() -- ScreenGui:Destroy()
--script:Destroy() -- script:Destroy()
--time to make the fanboys rage... --time to make the fanboys rage...
Tabify() Tabify()
end end
@ -2232,19 +2167,14 @@ local function AttachScrollWheel()
if ScrollWheelConnections then if ScrollWheelConnections then
return return
end end
ScrollWheelConnections = {} ScrollWheelConnections = {
table.insert(
ScrollWheelConnections,
Mouse.WheelForward:connect(function() Mouse.WheelForward:connect(function()
OnScrollWheelMove(0.05) OnScrollWheelMove(0.05)
end) end),
)
table.insert(
ScrollWheelConnections,
Mouse.WheelBackward:connect(function() Mouse.WheelBackward:connect(function()
OnScrollWheelMove(-0.05) OnScrollWheelMove(-0.05)
end) end),
) }
end end
local function DetachScrollWheel() local function DetachScrollWheel()
@ -2271,6 +2201,58 @@ end)
-- Scroll Bar functions -- Scroll Bar functions
------------------------ ------------------------
--[[
Utility function to create buttons for the popup menus
@Args:
nparent what to parent this button to
ntext text to put on this button
index number index of this entry in menu
last is this the last element of the popup menu
@Return: a popup menu button
--]]
local function MakePopupButton(nparent, ntext, index, last)
local tobj = New "ImageButton" {
Name = "ReportButton",
BackgroundTransparency = 1,
Position = UDim2.new(0, 0, 1 * index, 0),
Size = UDim2.new(1, 0, 1, 0),
ZIndex = 7,
New "TextLabel" {
Name = "ButtonText",
BackgroundTransparency = 1,
Position = UDim2.new(0.07, 0, 0.07, 0),
Size = UDim2.new(0.86, 0, 0.86, 0),
Parent = HeaderFrame,
Font = "ArialBold",
Text = ntext,
FontSize = "Size14",
TextScaled = true,
TextColor3 = Color3.new(1, 1, 1),
TextStrokeTransparency = 1,
ZIndex = 7,
},
Parent = nparent,
}
if index == 0 then
tobj.Image = "http://banland.xyz/asset?id=97108784"
elseif last then
if index % 2 == 1 then
tobj.Image = "http://banland.xyz/asset?id="
.. Images.LightPopupBottom
else
tobj.Image = "http://banland.xyz/asset?id="
.. Images.DarkPopupBottom
end
else
if index % 2 == 1 then
tobj.Image = "http://banland.xyz/asset?id=97112126"
else
tobj.Image = "http://banland.xyz/asset?id=97109338"
end
end
return tobj
end
--[[ --[[
prepares the needed popup to be tweened on screen, and updates the position of the popup clip prepares the needed popup to be tweened on screen, and updates the position of the popup clip
frame to match the selected player frame's position frame to match the selected player frame's position
@ -3430,6 +3412,6 @@ InitReportAbuse()
AreNamesExpanded.Value = true AreNamesExpanded.Value = true
BaseUpdate() BaseUpdate()
--UGGGLY,find a better way later -- UGGGLY, find a better way later
-- wait(2) -- wait(2)
-- IsPersonalServer = not not game.Workspace:FindFirstChild "PSVariable" -- IsPersonalServer = not not game.Workspace:FindFirstChild "PSVariable"