the cutting room mirror

Unused Scripts

This is a sub-page of Roblox (Engine).

DebugDraw#

Found in content\avatar\scripts\RobloxCharacterPackages-0.0.1.rbxm under RobloxCharacterPackages.RobloxCharacterPackages.CharacterController.Dev.DebugDraw.

local srcPath = game.ReplicatedStorage.RobloxCharacterPackages.CharacterController
local Util = require(srcPath.Utils.Util)

local DebugDraw = {}

-- Forward declare private functions
local _drawDashedLine
local _initSeries
local _getSeriesDrawContext
local _getGenericDrawContext

DebugDraw.config = {
    -- Default color for a plot, if not passed via plotPoint()
    defaultPlotColor = Color3.fromRGB(255, 255, 255),

    -- Background color for the graph
    plotBGColor = Color3.fromRGB(0, 0, 0),

    -- Graph position relative to player
    graphPosition = Vector3.new(-30, 0, -20),

    -- Graph width/height
    graphDimensions = Vector3.new(60, 10, 0),

    -- The number of plots to fit inside the fixed graphDimensions. More plots
    -- make the graph draw slower. Graph resets after filling up.
    maxPlots = 1200,

    -- Margins between plots and edge of graph
    margin = Vector3.new(0, .5, 0),

    -- Draw a dotted line at zero
    drawZeroLine = true,

    -- Force a min/max, else auto-calculate the current running min/max
    fixedMin = nil,
    fixedMan = nil,
}

-- Nested data structure storing state for each series. See _initSeries().
DebugDraw.series = {}

--[[
USAGE:
DebugDraw.config.drawZeroLine = false
DebugDraw.plotPoint("PosX", humanoid.RootPart.Position.X, Color3.fromRGB(255, 0, 0))
DebugDraw.plotPoint("PosY", humanoid.RootPart.Position.Y, Color3.fromRGB(0, 255, 0))
DebugDraw.plotPoint("PosZ", humanoid.RootPart.Position.Z, Color3.fromRGB(0, 120, 255))
--]]
function DebugDraw.plotPoint(key: string, value: number, color: Color3?)
    local graphDimensions = DebugDraw.config.graphDimensions
    local lowerLeft = Vector3.zero - (graphDimensions / 2) + DebugDraw.config.margin
    local upperRight = Vector3.zero + (graphDimensions / 2) - DebugDraw.config.margin
    local drawContext = _initSeries(key, color).drawContext
    if drawContext == nil then
        return
    end

    -- Start over if we've hit the graph width
    if (#DebugDraw.series[key].values > DebugDraw.config.maxPlots) then
        DebugDraw.series[key].values = {}
    end

    drawContext:Clear()

    -- Initialize min/max values
    if DebugDraw.series[key].minValue == nil then
        DebugDraw.series[key].minValue = value
    end
    if DebugDraw.series[key].maxValue == nil then
        DebugDraw.series[key].maxValue = value
    end
    
    -- Track min/max values to auto-scale the graph, or just use the min/max
    -- passed in via config.
    if (DebugDraw.config.minValue == nil) then
        if value < DebugDraw.series[key].minValue then
            DebugDraw.series[key].minValue = value
        end
    else
        DebugDraw.series[key].minValue = DebugDraw.config.minValue
    end

    if (DebugDraw.config.maxValue == nil) then
        if value > DebugDraw.series[key].maxValue then
            DebugDraw.series[key].maxValue = value
        end
    else
        DebugDraw.series[key].maxValue = DebugDraw.config.maxValue
    end

    -- Add this value to the list of all values
    -- XXX: This method assumes a constant deltaTime. Could store pairs of
    --      gameTime/value, but iterating over lua tables like this was ugly.
    table.insert(DebugDraw.series[key].values, value)

    -- Draw zero line
    if DebugDraw.config.drawZeroLine then
        local remappedZero = Util.remapClamped(
            0,
            DebugDraw.series[key].minValue,
            DebugDraw.series[key].maxValue,
            lowerLeft.Y,
            upperRight.Y
        )

        local zeroInRange = remappedZero > DebugDraw.series[key].minValue and
            remappedZero < DebugDraw.series[key].maxValue
        if zeroInRange then
            _drawDashedLine(
                drawContext,
                Vector3.new(lowerLeft.X, remappedZero, 0),
                Vector3.new(upperRight.X, remappedZero, 0)
            )
        end
    end

    -- Don't draw anything until we have at least 2 plots
    if (#DebugDraw.series[key].values < 2) then
        return
    end

    -- Plot all values
    local lastValue = nil
    local lastTime = nil
    for i, val in ipairs(DebugDraw.series[key].values) do
        -- Start plotting from the second index
        if i < 2 then
            continue
        end

        -- Remap values to min/max of graph
        local remappedValue = Util.remapClamped(
            val,
            DebugDraw.series[key].minValue,
            DebugDraw.series[key].maxValue,
            lowerLeft.Y,
            upperRight.Y)

        -- Remap time to min/max of graph
        local remappedTime = Util.remapClamped(
            i - 1,
            1,
            DebugDraw.config.maxPlots,
            lowerLeft.X,
            upperRight.X)

        -- Handle first time we plot
        if lastValue == nil then
            lastValue = remappedValue
        end
        if lastTime == nil then
            lastTime = remappedTime
        end

        -- Draw a line between this point and the last point
        local lastPoint: Vector3 = Vector3.new(lastTime, lastValue, 0)
        local curPoint: Vector3 = Vector3.new(remappedTime, remappedValue, 0)
        drawContext:AddLine(
            lastPoint,
            curPoint
        )

        -- Store last point for next iteration
        lastValue = remappedValue
        lastTime = remappedTime
    end
end

function DebugDraw.drawLine(point1: Vector3, point2: Vector3, color: Color3?)
    local debugDraw = _getGenericDrawContext()
    color = color or Color3.fromRGB(255, 255, 255)

    debugDraw.Color3 = color

    debugDraw:AddLine(point1, point2)
    return debugDraw
end

function DebugDraw.drawRay(origin: Vector3, ray: Vector3, color: Color3?)
    local debugDraw = _getGenericDrawContext()
    color = color or Color3.fromRGB(255, 255, 255)

    debugDraw.Color3 = color

    debugDraw:AddLine(origin, origin + ray)
    return debugDraw
end

function DebugDraw.clear()
    local debugDraw = _getGenericDrawContext()
    debugDraw:Clear()
end

_drawDashedLine = function(debugDraw, point1: Vector3, point2: Vector3)
    local length = (point2 - point1).Magnitude
    local step = .25 / length

    local dashRatio = .5
    for t = 0, 1 - step, step  do

        debugDraw:AddLine(
            point1:Lerp(point2, t),
            point1:Lerp(point2, t + (step * dashRatio))
        )
    end
end

_initSeries = function(key: string, color: Color3?)
    color = color or DebugDraw.config.defaultPlotColor

    if DebugDraw.series[key] ~= nil then
        -- Cached series
        return DebugDraw.series[key]

    else
        -- Construct new series
        DebugDraw.series[key] = {
            values = {},
            minValue = nil,
            maxValue = nil,
        }
        DebugDraw.series[key].drawContext = _getSeriesDrawContext(key)
        DebugDraw.series[key].drawContext.Color3 = color
        return DebugDraw.series[key]
    end
end

_getSeriesDrawContext = function(key: string)
    if DebugDraw.series[key].drawContext ~= nil then
        return DebugDraw.series[key].drawContext
    end

    -- Create plot frame
    local plotFrame = Instance.new("Part")
    plotFrame.Parent = workspace
    plotFrame.Name = "debugPlotFrame_"..key
    plotFrame.Anchored = true
    plotFrame.CanCollide = false
    plotFrame.CanQuery = false
    plotFrame.CanTouch = false
    plotFrame.Size = DebugDraw.config.graphDimensions
    plotFrame.Color = DebugDraw.config.plotBGColor

    local playerPos = game.Players.LocalPlayer.Character.HumanoidRootPart.Position
    plotFrame.Position = playerPos + DebugDraw.config.graphPosition +
        (DebugDraw.config.graphDimensions / 2)

    -- Create drawing context
    local drawContext = Instance.new("WireframeHandleAdornment")
    drawContext.Parent = plotFrame
    drawContext.Name = "debugDraw_"..key
    drawContext.Adornee = plotFrame

    -- Cache the drawing context
    DebugDraw.series[key].drawContext = drawContext

    return drawContext
end

_getGenericDrawContext = function()
    if DebugDraw.genericDrawContext ~= nil then
        return DebugDraw.genericDrawContext
    end

    -- Create drawing context
    local drawContext = Instance.new("WireframeHandleAdornment")
    local owner = Instance.new("Part")
    owner.Parent = workspace
    owner.Name = "debugDraw_genericOwner"
    owner.Anchored = true
    owner.CanCollide = false
    owner.CanQuery = false
    owner.CanTouch = false
    
    drawContext.Parent = owner
    drawContext.Name = "debugDraw_genericDrawContext"
    drawContext.Adornee = owner

    -- Cache the drawing context
    DebugDraw.genericDrawContext = drawContext

    return drawContext
end

return DebugDraw

DebugVisual#

Found in content\avatar\scripts\RobloxCharacterPackages-0.0.1.rbxm under RobloxCharacterPackages.RobloxCharacterPackages.CharacterController.Utils.DebugVisual.

local DebugVisual = {}

local DEBUG_VISUAL = false

local RED = Color3.new(1,0,0)
local GREEN = Color3.new(0,1,0)
local WHITE = Color3.new(1,1,1)

local MAX_POOL_SIZE = 500
DebugVisual.debugLHAPool = {}
DebugVisual.nextLHAIndex = 1

local MAX_POOL_SIZE_SPHERE = 10
DebugVisual.debugSpherePool = {}
DebugVisual.nextSphereIndex = 1

-- Line
function DebugVisual:DrawLine(origin : Vector3, dir : Vector3, color : Color3)
    if not DEBUG_VISUAL then
        return
    end

    local lha = self:GetNextDebugLHA()
    lha.Color3 = color
    lha.Length = dir.Magnitude
    lha.CFrame = CFrame.new(origin, origin + dir)
    lha.Visible = true
end

function DebugVisual:ClearRays()
    for i, lha in ipairs(self.debugLHAPool) do
        lha.Visible = false
    end
    self.nextLHAIndex = 1
end

function DebugVisual:GetNextDebugLHA()
    if self.nextLHAIndex > MAX_POOL_SIZE then
        self.nextLHAIndex = 1
    end

    local lha = self.debugLHAPool[self.nextLHAIndex]
    if not lha then
        lha = Instance.new("LineHandleAdornment")
        lha.Name = "LHA_" .. tostring(#self.debugLHAPool+1)
        lha.Color3 = Color3.new(1,1,1)
        lha.Thickness = 4
        lha.ZIndex = 0
        lha.Adornee = game.Workspace.Terrain
        lha.Parent = game.Workspace.Terrain
        lha.Transparency = 0.5
        table.insert(self.debugLHAPool,lha)
    end
    self.nextLHAIndex = self.nextLHAIndex + 1
    return lha
end

-- Sphere
function DebugVisual:DrawSphere(origin : Vector3, radius : number, color : Color3)
    if not DEBUG_VISUAL then
        return
    end

    local d = radius * 2
    local sOrigin = self:GetNextDebugSphere()
    sOrigin.Color = color
    sOrigin.Position = origin
    sOrigin.Size = Vector3.new(d, d, d)
    sOrigin.Transparency = 0.95
end

function DebugVisual:ClearSpheres()
    for i, s in ipairs(self.debugSpherePool) do
        s.Transparency = 1
    end
    self.nextSphereIndex = 1
end

function DebugVisual:GetNextDebugSphere()
    if self.nextSphereIndex > MAX_POOL_SIZE_SPHERE then
        self.nextSphereIndex = 1
    end

    local s = self.debugSpherePool[self.nextSphereIndex]
    if not s then
        s = Instance.new("Part")
        s.Shape = "Ball"
        s.Material = Enum.Material.SmoothPlastic
        s.CollisionGroup = "PosedCloneGhostGroup"
        s.Anchored = true
        s.Name = "Sphere_" .. tostring(#self.debugSpherePool+1)
        s.Color = Color3.new(1, 1, 1)
        s.Size = Vector3.new(1, 1, 1)
        s.Position = Vector3.new()
        s.Parent = game.Workspace.Terrain
        s.Transparency = 0.9
        table.insert(self.debugSpherePool, s)
    end
    self.nextSphereIndex = self.nextSphereIndex + 1
    return s
end

-- Ray cast visual with hit normal
function DebugVisual:DrawRayCast(origin : Vector3, dir : Vector3, result : RaycastResult)
    if not DEBUG_VISUAL then
        return
    end

    local color = if result then GREEN else WHITE
    self:DrawLine(origin, dir, color)

    if result then
        self:DrawLine(result.Position, result.Normal, RED)
    end
end

-- Sphere cast visual with hit normal
function DebugVisual:DrawSphereCast(origin : Vector3, dir : Vector3, radius : number, result : RaycastResult)
    if not DEBUG_VISUAL then
        return
    end

    local color = if result then GREEN else WHITE
    self:DrawSphere(origin, radius, color)
    self:DrawSphere(origin + dir, radius, color)
    
    if result then
        self:DrawLine(result.Position, result.Normal, RED)
    end
end

-- Self cleanup for debug visuals (refreshes 1/10th of the visual per heartbeat)
if DEBUG_VISUAL then
    game:GetService("RunService").Heartbeat:Connect(function(dt)
        for i = 1, math.floor(MAX_POOL_SIZE / 10) do
            DebugVisual:DrawLine(Vector3.new(), Vector3.new(), Color3.new(1, 1, 1))
        end

        for i = 1, math.floor(MAX_POOL_SIZE_SPHERE / 10) do
            DebugVisual:DrawSphere(Vector3.new(), 1, Color3.new(1, 1, 1))
        end
    end)
end

return DebugVisual

EmulatedRootMotionClip#

Found in content\avatar\scripts\RobloxCharacterPackages-0.0.1.rbxm under RobloxCharacterPackages.RobloxCharacterPackages.CharacterController.Utils.EmulatedRootMotionClip. This script is listed to only be used for testing.

-- THIS SHOULD BE USED FOR TESTING
-- If something needs RM, just export it with the animation
local Layer = require(game.ReplicatedStorage.RobloxCharacterPackages.MotionCompositor.Base.Layer)

-- Emulates linear constant root motion when defined in config
local EmulatedRootMotionClip = Layer:extend("EmulatedRootMotionClip")

EmulatedRootMotionClip.defaultProps = {
    speed = 0,
    dt = 0,
}

function EmulatedRootMotionClip:update(dt)
    for _, layer in self.children do
        layer:update(dt)
    end
end

function EmulatedRootMotionClip:getDuration(): number
    if #self.children == 1 then
        return self.children[1]:getDuration()
    end
    return 0
end

function EmulatedRootMotionClip:updateToPhase(phase: number)
    if #self.children == 1 then
        self.children[1]:updateToPhase(phase)
    end
end

function EmulatedRootMotionClip:evaluate(mask)
    local pose = if #self.children == 1
        then self.children[1]:evaluate(mask)
        else mask:CreateEmptyPose()

    -- The dir vector is just taken as character space forward hence (0, 0, -1)
    pose:SetTranslation("RootMotionDelta", Vector3.new(0, 0, -1) * self.props.speed * self.props.dt)

    return pose
end

return EmulatedRootMotionClip

SensorUtil#

Found in content\avatar\scripts\RobloxCharacterPackages-0.0.1.rbxm under RobloxCharacterPackages.RobloxCharacterPackages.CharacterController.Utils.SensorUtil. It's possible that only the debug parts are actually unused. So far no uses of this module have been found.

local SensorUtil = {}

local DEBUG_VISUAL = false

local UP = Vector3.new(0, 1, 0)
local DOWN = Vector3.new(0, -1, 0)
local FORWARD = Vector3.new(0, 0, -1)

-- Distribute points evenly using spiral sunflower pattern 
local goldenAngle = math.pi * (3 - math.sqrt(5))
local pi2 = 2 * math.pi

local Players = game:GetService("Players")
local Utils = game.ReplicatedStorage.RobloxCharacterPackages.CharacterController.Utils
local TemporalCache = require(Utils.TemporalCache)
local DebugVisual = require(Utils.DebugVisual)
SensorUtil.scanCache = {}

-- TODO: keep the results for a forward cast globally for all abilities to use??

local function orthogonal(v : Vector3)
    local dir = v.Unit

    if dir.x ~= 0 or dir.y ~= 0 then
        return Vector3.new(-dir.y, dir.x, 0).Unit
    else
        return Vector3.new(0, -dir.z, dir.y).Unit
    end
end

local function randFloat(min, max)
    local range = max - min
    local randomValue = math.random() * range + min
    return randomValue
end

function SensorUtil:Raycast(origin, dir : Vector3, raycastParams : RaycastParams)
    if typeof(origin) == "CFrame" then
        origin = origin.Position
    end

    local result = nil
    if raycastParams then
        result = game.Workspace:Raycast(origin, dir, raycastParams)
    else
        result = game.Workspace:Raycast(origin, dir)
    end
    DebugVisual:DrawRayCast(origin, dir, result)
    
    return result
end

-- Based on a microprofiling, Spherecast cost is roughly a handful of Raycasts (~ 4:1 ratio)
-- May vary based on the casting radius.
-- Spherecast would likely be preferred with simple linear area scans where we mostly care if something is hit
function SensorUtil:SphereScan(scanParams)
    local radius = scanParams.radius or 0.5
    local result = game.Workspace:Spherecast(scanParams.origin, radius, scanParams.dir, scanParams.raycastParams)
    DebugVisual:DrawSphereCast(scanParams.origin, scanParams.dir, radius, result)

    if not result then
        return {}
    end

    -- TODO: investigate adding a temporal version of spherecast with option where filtered hit ancestors get added to the raycastparam instance filters
    -- This is so the scan can eventually hit objects that may be obscured by other instances which the filter function wants to ignore
    local filterFn = scanParams.filter
    if not filterFn then
        return {result}
    end

    if filterFn(result) then
        return {result}
    end

    return {}
end

-- Cast a approximate cylindrical volume from a circular plane
-- Distribute rays in sunflower seed pattern and locally randomize a shift based on the average point density
-- Pattern rotation is modded over time to try and guarantee some level of uniform sampling
-- Spread can be adjusted for casting in a cone shape
function SensorUtil:RaycastScan(scanParams)
    -- These are the minimal required params
    local origin = scanParams.origin
    local dir = scanParams.dir

    -- raycastParams can be nil but not filtering is not recommended
    local raycastParams = scanParams.raycastParams

    -- Default cast is basically a triangle cast of a 1 unit wide cylindrical volume
    local radius = scanParams.radius or 0.5
    local rayCount = scanParams.rayCount or 3
    local spread = scanParams.spread or 1

    if typeof(origin) == "CFrame" then
        origin = origin.Position
    end

    local results = {}
    if not origin then
        warn("RaycastScan missing parameter: origin")
        return results
    end

    if not dir then
        warn("RaycastScan missing parameter: dir")
        return results
    end

    -- Find two perpendicular unit vectors on the orthogonal plane
    local perp1 = orthogonal(dir)
    local perp2 = dir.Unit:Cross(perp1).Unit
    
    local timeOffset = tick() % pi2
    local ptRange = math.sqrt((math.pi * radius * radius) / rayCount) / 2
    local xOffset = randFloat(-ptRange, ptRange)
    local yOffset = randFloat(-ptRange, ptRange)

    local centerCast = origin + dir

    local insertFn = function (result)
        if result then
            table.insert(results, result)
        end
    end

    local filterFn = scanParams.filter
    if filterFn then
        insertFn = function (result)
            if result and filterFn(result) then
                table.insert(results, result)
            end
        end
    end

    for i = 1, rayCount do
        local angle = goldenAngle * i + timeOffset
        local r = math.sqrt(i / rayCount) * radius

        local x = r * math.cos(angle) + xOffset
        local y = r * math.sin(angle) + yOffset

        local result = nil
        local offset = x * perp1 + y * perp2
        local castSource = origin + offset
        if spread == 1.0 then
            result = self:Raycast(castSource, dir, raycastParams)
        else
            local dirSpread = (centerCast + offset * spread) - castSource
            result = self:Raycast(castSource, dirSpread, raycastParams)
        end

        insertFn(result)
    end

    return results
end

-- Similar to RaycastScan but uses a unique scanID to cache results for expireTime seconds
-- Offers a tradeoff between data staleness and performance (more comprehensive scan over time)
-- A particular instance will be able to have it's own cache with different sub caches
function SensorUtil:RaycastScanTemporal(scanParams, instance : Instance, scanID : string?, expireTime : number?)
    if not instance then
        warn("RaycastScanTemporal requires a instance.")
        return
    end

    scanID = scanID or "DEFAULT"
    expireTime = expireTime or 0.2

    if not SensorUtil.scanCache[instance] then
        SensorUtil.scanCache[instance] = {}
    end

    local cacheInstance = SensorUtil.scanCache[instance]
    if not cacheInstance[scanID] then
        cacheInstance[scanID] = TemporalCache:new(expireTime)
    end
    local cache = cacheInstance[scanID]

    local results = self:RaycastScan(scanParams)
    if results then
        cache:insert(results)
    end

    return cache:get()
end

-- Specific folder for posed clones
local workspace = game:GetService("Workspace")
local posedClonesFolder = workspace:FindFirstChild("posedClones")
if not posedClonesFolder then
    posedClonesFolder = Instance.new("Folder")
    posedClonesFolder.Name = "posedClones"
    posedClonesFolder.Parent = workspace
end

-- Returns a clone character that can be posed using the given animation (useful for pose prediction)
-- The hrp is returned to allow positioning, and animTrack allows selecting specific moment within the animation
function SensorUtil:posedClone(character:Model, animationAssetID:number)
    -- generate a unique identifier for the clone (used for tracking and clean up)
    local player = Players:GetPlayerFromCharacter(character)
    local UID = "Player-" .. player.UserId .. ":Animation-" .. tostring(animationAssetID)
    local oldClone = posedClonesFolder:FindFirstChild(UID)
    if oldClone then
        oldClone:Destroy()
    end

    -- Only archivable instances can be cloned
    character.Archivable = true
    local clonedCharacter:Model = character:Clone()
    character.Archivable = false
    clonedCharacter.Name = UID

    -- TODO: only temporarily instantiate the clone to collect info, destroy afterwards
    -- Remove unecessary instances in clone
    for _, d in ipairs(clonedCharacter:GetChildren()) do
        -- Remove all unecessary instances
        if not (d:IsA("BasePart") or d:IsA("Humanoid")) then
            d:Destroy()
        end
    end

    for _, d in ipairs(clonedCharacter:GetDescendants()) do
        if d:IsA("Decal") then
            d:Destroy()
        end

        -- Move all parts into non-colliding group
        if d:IsA("BasePart") then
            d.CollisionGroup = "PosedCloneGhostGroup"
            d.Transparency = math.max(d.Transparency, DEBUG_VISUAL and 0.5 or 1.0)
        end

        -- Reset all motors
        if d:IsA("Motor6D") then
            d.Transform = CFrame.new()
        end
    end

    -- add to workspace after removing scripts so they don't excute
    -- this should be done prior to animator stuff since animator needs to be part of the workspace before loading
    clonedCharacter.Parent = posedClonesFolder

    local animator = clonedCharacter:FindFirstChild("Animator", true)
    if not animator then
        animator = Instance.new("Animator")
        animator.Parent = clonedCharacter:FindFirstChildOfClass("Humanoid")
    end

    local animation = Instance.new("Animation")
    animation.AnimationId = "rbxassetid://" .. tostring(animationAssetID)

    -- The caller can control animTrack position in case they need a specific keyframe
    local animTrack = animator:LoadAnimation(animation)
    animTrack:Play()
    animTrack:AdjustSpeed(0)
    
    -- The caller can move the posed clone to the desired moment in animation
    local hrp = clonedCharacter:WaitForChild("HumanoidRootPart")
    hrp.Anchored = true

    return clonedCharacter, hrp, animTrack
end

function SensorUtil:AveragePosition(hits)
    local n = #hits
    if n == 0 then
        return nil
    end

    local totalPosition = Vector3.new(0, 0, 0)
    for _, hit in ipairs(hits) do
        totalPosition = totalPosition + hit.Position
    end

    return totalPosition / n
end


return SensorUtil

CharacterStateMachineCommon#

Found in content\avatar\scripts\RobloxCharacterPackages-0.0.1.rbxm under RobloxCharacterPackages.RobloxCharacterPackages.CharacterController.StateMachine.CharacterStateMachineCommon. This is not the entire script, this is only the DEBUG code.

local DEBUG = false

    if DEBUG then
        print("CCSM Created", CCSM, CCSM.definition)
    end

ServerMonitor#

Found in content\avatar\scripts\RobloxCharacterPackages-0.0.1.rbxm under RobloxCharacterPackages.RobloxCharacterPackages.CharacterController.StateMachine.ServerMonitor. This is not the entire script, this only contains parts with debug code.

local debug = false

function ServerMonitor:onServerHumanoidRemoteEventServer(
    player: Player,
    eventType: string,
    data: any
)
    if player == nil or player.Character == nil then
        return
    end

    if eventType == "ChangeStateSM" then
        -- changes to character state
        local changeStateData: commonTypes.ChangeStateSMRecord = data
        commonFuncs.SetState(changeStateData.character, changeStateData.newState)
        local humanoid = changeStateData.character:FindFirstChildOfClass("Humanoid")
        if changeStateData.newState == "Dead" then
            if
                self.trackedOwnershipList[changeStateData.character] == player
                and humanoid
                and humanoid.BreakJointsOnDeath
            then
                changeStateData.character:BreakJoints()
            end
        end
    elseif eventType == "ChangeCollisionSettings" then
        local settingsData: commonTypes.ChangeCollisionSettingsRecord = data
        if settingsData ~= nil and settingsData.character ~= nil then
            for k, v in pairs(settingsData.parts) do
                local part: Part? = settingsData.character:FindFirstChild(k)
                if part ~= nil then
                    part.CanCollide = v
                end
            end
        end
    elseif eventType == "RegisterHumanoidSM" then
        if debug then
            print("Server: New Humanoid", data)
        end
        self.trackedOwnershipList[data.characterModel] = player
    elseif eventType == "ContextDataHumanoidSM" then
        -- Received SM Context Information From Client
        if debug then
            print("Server: Received Context Data", data)
        end

        local contextXfer: commonTypes.ContextTransferDataType = data
        -- check to see if we're expecting a transfer
        local transferRecord: commonTypes.OwnerTransferDataType =
            self.humanoidUploadTransferInProgress[contextXfer.character]
        if transferRecord ~= nil then
            -- Check to see if we're expecting it from this Client
            if transferRecord.oldOwner == contextXfer.oldOwner then
                self.humanoidUploadTransferInProgress[contextXfer.character] = nil
                commonFuncs.SetState(contextXfer.character, contextXfer.currentState)
                if transferRecord.newOwner == nil then
                    -- server owned
                    local humanoid: Humanoid? =
                        contextXfer.character:FindFirstChildOfClass("Humanoid")
                    if humanoid ~= nil and humanoid.Parent ~= nil then
                        local localHumanoidStateMachineEventInstance: Instance =
                            game.ServerScriptService
                                :WaitForChild("StateMachineSystemServer")
                                :WaitForChild("LocalHumanoidStateMachineEvent")
                        local localHumanoidStateMachineEvent: BindableEvent = nil

                        if localHumanoidStateMachineEventInstance:IsA("BindableEvent") then
                            localHumanoidStateMachineEvent = localHumanoidStateMachineEventInstance
                        end

                        if localHumanoidStateMachineEvent == nil then
                            print(
                                "Error !! Expecting LocalHumanoidStateMachineEvent under the character model"
                            )
                        end
                        local record: commonTypes.RunningStateMachineRecord? =
                            commonFuncs.ContinueStateMachine(
                                contextXfer.character,
                                humanoid,
                                self.ccsmDefinition,
                                self.localEvent,
                                contextXfer.currentState,
                                contextXfer.context
                            )
                        self.runningStateMachines[contextXfer.character] = record
                    end

                    self.trackedOwnershipList[contextXfer.character] = "server"
                else
                    -- new client owner, send it to them
                    local newOwner = transferRecord.newOwner
                    local newTransferRecord: commonTypes.OwnerContextTransferDataType = {
                        oldOwner = transferRecord.oldOwner,
                        newOwner = newOwner,
                        currentState = contextXfer.currentState,
                        context = contextXfer.context,
                    }
                    self.humanoidStartupTransferInProgress[contextXfer.character] =
                        newTransferRecord

                    self.trackedOwnershipList[contextXfer.character] = newOwner
                    humanoidStateMachineUpdateEvent:FireClient(
                        newOwner,
                        "ContextDataHumanoidSM",
                        contextXfer
                    )
                end
            else
                warn("Unexpected context recieved from", contextXfer.oldOwner)
            end
        end
    elseif eventType == "ConfirmStartHumanoidSM" then
        if data ~= nil then
            local character: Model = data
            local startupRecord: commonTypes.OwnerContextTransferDataType? =
                self.humanoidStartupTransferInProgress[character]
            if startupRecord == nil then
                -- error
                if debug then
                    warn(
                        "Startup confirmation from unexpected client",
                        character,
                        self.humanoidStartupTransferInProgress
                    )
                end
            else
                -- check to verify that this client is supposed to own this
                if startupRecord.newOwner == player then
                    -- clear record
                    self.humanoidStartupTransferInProgress[character] = nil
                    self.trackedOwnershipList[character] = player
                else
                    warn(
                        "Unexpected client attempting to start up state machine",
                        player,
                        character
                    )
                end
            end
        end
    end
end

2013 Playerlist#

Downloaded at assetdelivery.roblox.com, found on the creator store at create.roblox.com. This is not the entire script, this only contains parts with debug code. Every line starting with a # isn't apart of the script and is added to provide more info on the code. Image of some of the debug code in action. (The code for this is located at the bottom of the script.)

# Line 321 to 326, only the debugprint() function is, well, debug.
function WaitForChild(parent,child)
    while not parent:FindFirstChild(child) do
        wait() debugprint(" child "..parent.Name.." waiting for "..child)
    end
    return parent[child]
end

# Line 896 to 935.
local debugFrame = Obj.Create"Frame"
    {
        Name = 'debugframe',
        Position = UDim2.new(0, 0, 0, 0),
        Size = UDim2.new(0, 150, 0, 800),--0.99000001
        BackgroundTransparency = 1,
        
    }
    local debugplayers = Obj.Create"TextLabel"
    {
        BackgroundTransparency = .8,
        Position = UDim2.new(0, 0, .01, 0),
        Size = UDim2.new(1,0,.5,0),
        Parent = debugFrame,
        Font = 'ArialBold',
        Text = '--',
        FontSize='Size14',
        TextWrapped=true,
        TextColor3 = Color3.new(1,1,1),
        TextStrokeColor3 = Color3.new(0,0,0),
        TextStrokeTransparency = 0,
        TextXAlignment = 'Right',
        TextYAlignment = 'Center',
    }
    local debugOutput = Obj.Create"TextLabel"
    {
        BackgroundTransparency = .8,
        Position = UDim2.new(0, 0, .5, 0),
        Size = UDim2.new(1,0,.5,0),
        Parent = debugFrame,
        Font = 'ArialBold',
        Text = '--',
        FontSize='Size14',
        TextWrapped=true,
        TextColor3 = Color3.new(1,1,1),
        TextStrokeColor3 = Color3.new(0,0,0),
        TextStrokeTransparency = 0,
        TextXAlignment = 'Right',
        TextYAlignment = 'Center',
    }   

# Line 938 to 947.
--[[
    simple function to toggle the display of debug output
--]]
local DebugPrintEnabled=true
function debugprint(str)
    --print(str)
    if DebugPrintEnabled then
        debugOutput.Text=str
    end
end

# Line 1145 to 1179, only the debug() function is, debug.
function WaitForClick(frameParent,polledFunction,exitFunction)
    
    if WaitForClickLock then return end
    WaitForClickLock=true
    local upHappened=false
    local connection, connection2
    connection=BigButton.MouseButton1Up:connect(function(nx,ny)
        exitFunction(nx,ny)
        BigButton.Visible=false
        connection:disconnect()
        if connection2 then
            connection2:disconnect()
        end
        --debugprint('mouse up!')
    end)
    connection2=BigButton.MouseMoved:connect( function(nx,ny)
        polledFunction(nx,ny)
        
    end)
    
    --debugprint('waiting for click!')
    BigButton.Visible=true
    BigButton.Active=true
    BigButton.Parent=frameParent
    frameParent.AncestryChanged:connect(function(child,nparent) 
        if child == frameParent and nparent ==nil then
            exitFunction(nx,ny)
            BigButton.Visible=false
            connection:disconnect()
            connection2:disconnect()
            debugprint("forced out of wait for click")
        end
    end)
    WaitForClickLock=false
end

# Line 1230 to 1234, only debugprint() is debug.
function OnPrivilegeLevelSelect(player,nlevel,BanPlayerButton,VisitorButton,MemberButton,AdminButton)
    debugprint('setting privilege level')
    SetPrivilegeRank(player,nlevel)
    HighlightMyRank(player,BanPlayerButton,VisitorButton,MemberButton,AdminButton)
end

# Line 1259 to 1280, only debugprint() is debug.
 --------------------------  
 -- Report abuse handling
 -------------------------- 
--[[
    does final reporting of abuse on selected player, calls closeAbuseDialog
--]]
function OnSubmitAbuse()
    if SubmitReportButton.Active then
        if AbuseName and SelectedPlayer then
            AbuseSettingsFrame.Visible = false
            game.Players:ReportAbuse(SelectedPlayer, AbuseName, AbuseDescriptionBox.Text)
            if AbuseName == "Rude or Mean Behavior" or AbuseName == "False Reporting Me" then
                CalmingAbuseBox.Parent = ReportAbuseShield
            else
                debugprint('opening abuse box')
                NormalAbuseBox.Parent = ReportAbuseShield
            end
        else
            CloseAbuseDialog()
        end
    end
end

# Line 1282 to 1294, only debugfunction() is debug.
--[[
    opens the abuse dialog, initialises text to display selectedplayer
--]]
function OpenAbuseDialog()
    debugprint('adding report dialog')
    AbusePlayerLabel.Text = SelectedPlayer.Name
    --AbuseDescriptionBox.Text = ""
    PopUpPanel:TweenPosition(UDim2.new(1,0,0,0), "Out", "Linear", BASE_TWEEN,true)
    AbuseDescriptionBox=OriginalAbuseDescriptionBox:Clone()
    AbuseDescriptionBox.Parent = AbuseDescriptionWrapper
    ReportAbuseShield.Parent = ScreenGui
    ClosePopUpPanel()
end

# Line 1440 to 1452, only debugprint() is debug. Function does continue after this point, it doesn't end here.
--[[
    Called when stat is added
    if playerEntry is localplayer, will add to score names and re-sort the stats, and resize the width of the leaderboard
    for all players, will add a listener for if this stat changes
    if stat is a string value, crashes the leaderboard
    Note:change crash to a 'tabify' leaderboard later
    @Args:
    nchild          new child value to leaderstats
    playerEntry     entry this stat was added to
--]]
function StatAdded(nchild,playerEntry)
 -- dont re - add a leaderstat I alreday have
    while AddingStatLock do debugprint('in stat added function lock') wait(1/30) end

# Line 1502 to 1512, only debugprint() is debug. Function does continue after this point, it doesn't end here.
--[[
    Called when stat is removed from player
    for all players, destroys the stat frame associated with this value,
    then calls statchanged(to resize frame)
    if playerEntry==localplayer, will remove from scorenames
    @Args:
    nchild          ___value to be removed
    playerEntry     entry of player value is being removed from
--]]
function StatRemoved(nchild,playerEntry)
    while AddingStatLock do debugprint('In Adding Stat Lock1') wait(1/30) end
    AddingStatLock = true
    if playerEntry['Frame']:FindFirstChild(nchild.Name) then
        debugprint('Destroyed frame!')
        playerEntry['Frame'][nchild.Name].Parent = nil
    end

# Line 1578 to 1582, only debugprint() is debug.
    if scoreval['Name'] == ScoreNames[1]['Name'] then
        debugprint('changing score')
        entry['Score'] = GetScoreValue(thisScore)
        if entry['Player'] == LocalPlayer then HeaderScore.Text = tostring(GetScoreValue(thisScore)) end
    end

# Line 1612 to 1667, only debugprint() is debug.
function RecreateScoreColumns(ptable)
    while AddingStatLock do debugprint ('In Adding Stat Lock2') wait(1/30) end
    AddingStatLock = true
    local Xoffset=5--15 --current offset from Right
    local maxXOffset=Xoffset
    local MaxSizeColumn=0 --max size for this column
    
    -- foreach known leaderstat
    for j = #ScoreNames, 1,-1 do
        local scoreval = ScoreNames[j]

        MaxSizeColumn=0
        -- for each entry in this player table
        for i,entry in ipairs(ptable) do
            local panel = entry['Frame']
            local tplayer = entry['Player']
            -- if this panel does not have an element named after this stat
            if not panel:FindFirstChild(scoreval['Name']) then
                -- make an entry for this object
                local nentry = MakeScoreEntry(entry,scoreval,panel)
                if nentry then
                    debugprint('adding '..nentry.Name..' to '..entry['Player'].Name )
                    nentry.Parent = panel
                    -- add score to team
                    if entry['MyTeam'] and entry['MyTeam'] ~= NeutralTeam and not entry['MyTeam']['Frame']:FindFirstChild(scoreval['Name']) then
                        local ntitle = nentry:Clone()
                        --ntitle.TextXAlignment  = 'Right'
                        ntitle.Parent = entry['MyTeam']['Frame']
                    end
                    
                end
            end
            scoreval['XOffset']=Xoffset

            if panel:FindFirstChild(scoreval['Name']) then
                MaxSizeColumn=math.max(MaxSizeColumn,panel[scoreval['Name']].TextBounds.X)
            end
        end

        if AreNamesExpanded.Value then
            MaxSizeColumn=math.max(MaxSizeColumn,StatTitles[scoreval['Name'] ].TextBounds.X)
            StatTitles[scoreval['Name'] ]:TweenPosition(UDim2.new(RightEdgeSpace,-Xoffset,0,0),'Out','Linear',BASE_TWEEN,true)
        else
            StatTitles[scoreval['Name'] ]:TweenPosition(UDim2.new((.4+((.6/#ScoreNames)*(j-1)))-1,0,0,0),'Out','Linear',BASE_TWEEN,true)
        end
        scoreval['ColumnSize']=MaxSizeColumn
        Xoffset= Xoffset+SpacingPerStat+MaxSizeColumn
        maxXOffset=math.max(Xoffset,maxXOffset)
    end
    NormalBounds = UDim2.new(0, BaseScreenXSize+maxXOffset-SpacingPerStat,0,800)
    NormalPosition = UDim2.new(1 , -NormalBounds.X.Offset, NormalPosition.Y.Scale, 0)
    UpdateHeaderNameSize()
    UpdateMaximize()
    
    AddingStatLock = false
end

# Line 1929 to 2012, only debugprint() is debug.
function RecreateScoreColumns(ptable)
    while AddingStatLock do debugprint ('In Adding Stat Lock2') wait(1/30) end
    AddingStatLock = true
    local Xoffset=5--15 --current offset from Right
    local maxXOffset=Xoffset
    local MaxSizeColumn=0 --max size for this column
    
    -- foreach known leaderstat
    for j = #ScoreNames, 1,-1 do
        local scoreval = ScoreNames[j]

        MaxSizeColumn=0
        -- for each entry in this player table
        for i,entry in ipairs(ptable) do
            local panel = entry['Frame']
            local tplayer = entry['Player']
            -- if this panel does not have an element named after this stat
            if not panel:FindFirstChild(scoreval['Name']) then
                -- make an entry for this object
                local nentry = MakeScoreEntry(entry,scoreval,panel)
                if nentry then
                    debugprint('adding '..nentry.Name..' to '..entry['Player'].Name )
                    nentry.Parent = panel
                    -- add score to team
                    if entry['MyTeam'] and entry['MyTeam'] ~= NeutralTeam and not entry['MyTeam']['Frame']:FindFirstChild(scoreval['Name']) then
                        local ntitle = nentry:Clone()
                        --ntitle.TextXAlignment  = 'Right'
                        ntitle.Parent = entry['MyTeam']['Frame']
                    end
                    
                end
            end
            scoreval['XOffset']=Xoffset

            if panel:FindFirstChild(scoreval['Name']) then
                MaxSizeColumn=math.max(MaxSizeColumn,panel[scoreval['Name']].TextBounds.X)
            end
        end

        if AreNamesExpanded.Value then
            MaxSizeColumn=math.max(MaxSizeColumn,StatTitles[scoreval['Name'] ].TextBounds.X)
            StatTitles[scoreval['Name'] ]:TweenPosition(UDim2.new(RightEdgeSpace,-Xoffset,0,0),'Out','Linear',BASE_TWEEN,true)
        else
            StatTitles[scoreval['Name'] ]:TweenPosition(UDim2.new((.4+((.6/#ScoreNames)*(j-1)))-1,0,0,0),'Out','Linear',BASE_TWEEN,true)
        end
        scoreval['ColumnSize']=MaxSizeColumn
        Xoffset= Xoffset+SpacingPerStat+MaxSizeColumn
        maxXOffset=math.max(Xoffset,maxXOffset)
    end
    NormalBounds = UDim2.new(0, BaseScreenXSize+maxXOffset-SpacingPerStat,0,800)
    NormalPosition = UDim2.new(1 , -NormalBounds.X.Offset, NormalPosition.Y.Scale, 0)
    UpdateHeaderNameSize()
    UpdateMaximize()
    
    AddingStatLock = false
end

# Line 2153 to 2159, only debugprint() is debug.
--]]
function LeaderstatsRemoved(oldLeaderstats,playerEntry)
    while AddingFrameLock do debugprint('waiting to insert '..playerEntry['Player'].Name) wait(1/30) end 
    AddingFrameLock = true
    RemoveAllStats(playerEntry)
    AddingFrameLock = false
end

# Line 2176 to 2187, only debugprint() is debug. Function does continue after this point, it doesn't end here.
function InitMovingPanel( entry, player)
    PopUpClipFrame.Parent= ScreenGui
    
    if PopUpPanel then
        PopUpPanel:Destroy()
    end
    PopUpPanel= PopUpPanelTemplate:Clone()
    PopUpPanel.Parent= PopUpClipFrame
    
    local nextIndex = 2
    local friendStatus = GetFriendStatus(player)
    debugprint (tostring(friendStatus))

# Line 2300 to 2308, only debugprint() is debug. Function does continue after this point, it doesn't end here.
--[[
    this one's a doozie, happens when a player is added to the game
    inits their player frame and player entry, assigns them to a team if possible,
    and hooks up their leaderstats
    @Args:
    nplayer     new player object to insert
--]]
function InsertPlayerFrame(nplayer)
    while AddingFrameLock do debugprint('waiting to insert '..nplayer.Name) wait(1/30) end 

# Line 2403 to 2411, only debugprint() is debug.
    nplayer.ChildAdded:connect(function(nchild) 
        if nchild.Name == 'leaderstats' then
            while AddingFrameLock do debugprint('in adding leaderstats lock') wait(1/30) end
            if not nplayer:FindFirstChild("leaderstats") then return end
            AddingFrameLock = true
            LeaderstatsAdded(nentry)
            AddingFrameLock = false
        end
    end)

# Line 2429 to 2434, only debugprint() is debug. Function does continue after this point, it doesn't end here.
--[[
    Note:major optimization can be done here
    removes this player's frame if it exists, calls base update
--]]
function RemovePlayerFrame(tplayer)
    while AddingFrameLock do debugprint('in removing player frame lock') wait(1/30) end 

# Line 2618 to 2689, only debugprint() is debug.
function SetPlayerToTeam(entry)
    FindRemovePlayerFromTeam(entry)
    -- check to see if team exists, if it does add to that team
    local setToTeam = false
    for i,tframe in ipairs(TeamFrames) do
    -- add my entry on the new team
    if tframe['MyTeam'].TeamColor == entry['Player'].TeamColor then
            AddPlayerToTeam(tframe,entry)
            setToTeam = true
        end
    end
    -- if player was set to an invalid team, then set it back to neutral
    if not setToTeam and #(game.Teams:GetTeams())>0 then
        debugprint(entry['Player'].Name..'could not find team')
        entry['MyTeam']=nil
        if not NeutralTeam then 
            AddNeutralTeam()
        else AddPlayerToTeam(NeutralTeam,entry) end
    end
end

--[[
    Note:another big one, consiter breaking up
    called when any children of player changes
    handles 'Neutral', teamColor, Name and MembershipType changes
    @Args
    entry       Player entry changed
    property    name of property changed
--]]
function PlayerChanged(entry, property)
    while PlayerChangedLock do 
        debugprint('in playerchanged lock')
        wait(1/30)
    end
    PlayerChangedLock=true
    if property == 'Neutral' then
        -- if player changing to neutral
        if entry['Player'].Neutral and #(game.Teams:GetTeams())>0 then
            debugprint(entry['Player'].Name..'setting to neutral')
            FindRemovePlayerFromTeam(entry)
            entry['MyTeam']=nil
            if not NeutralTeam then
                debugprint(entry['Player'].Name..'creating neutral team')
                AddNeutralTeam()
            else
                debugprint(entry['Player'].Name..'adding to neutral team')
                AddPlayerToTeam(NeutralTeam,entry)
            end
        elseif #(game.Teams:GetTeams())>0 then -- else player switching to a team, or a weird edgecase
            debugprint(entry['Player'].Name..'has been set non-neutral')
            SetPlayerToTeam(entry)
        end
        BaseUpdate()
    elseif property == 'TeamColor' and not entry['Player'].Neutral and entry['Player'] ~= entry['MyTeam'] then
        debugprint(entry['Player'].Name..'setting to new team')
        SetPlayerToTeam(entry)
        BaseUpdate()
    elseif property == 'Name' or property == 'MembershipType' then
        entry['Frame']:FindFirstChild('BCLabel').Image = getMembershipTypeIcon(entry['Player'].MembershipType,entry['Player'].Name)
        entry['Frame'].Name = entry['Player'].Name
        entry['Frame'].TitleFrame.Title.Text = entry['Player'].Name
        if(entry['Frame'].BCLabel.Image ~= '') then
            entry['Frame'].TitleFrame.Title.Position=UDim2.new(.01, 30, .1, 0)
        end
        if entry['Player'] == LocalPlayer then
            entry['Frame'].TitleFrame.DropShadow.Text= entry['Player'].Name
            ChangeHeaderName(entry['Player'].Name)
        end
        BaseUpdate()
    end
    PlayerChangedLock=false
end

# Line 2691 to 2709, only debugprint() is debug.
function OnFriendshipChanged(player,friendStatus)

    Delay(.5,function()
        debugprint('friend status changed for:'..player.Name .." ".. tostring(friendStatus) .. " vs " .. tostring(GetFriendStatus(player)) )
        for _, entry in ipairs(PlayerFrames) do
            if entry['Player']==player then
                local nicon = getFriendStatusIcon(friendStatus)
                if nicon == '' and entry['Frame'].FriendLabel.Image ~= '' then
                    entry['Frame'].TitleFrame.Title.Position=entry['Frame'].TitleFrame.Title.Position-UDim2.new(0,17,0,0)
                elseif nicon ~= '' and entry['Frame'].FriendLabel.Image == '' then
                    entry['Frame'].TitleFrame.Title.Position=entry['Frame'].TitleFrame.Title.Position+UDim2.new(0,17,0,0)
                    debugprint('confirmed status:'..player.Name)
                end
                entry['Frame'].FriendLabel.Image = nicon
                return
            end
        end
    end)
end

# Line 2713 to 2718, only debugprint() is debug. Function does continue after this point, it doesn't end here.
function OnFriendshipChanged(player,friendStatus)

    Delay(.5,function()
        debugprint('friend status changed for:'..player.Name .." ".. tostring(friendStatus) .. " vs " .. tostring(GetFriendStatus(player)) )
        for _, entry in ipairs(PlayerFrames) do
            if entry['Player']==player then
                local nicon = getFriendStatusIcon(friendStatus)
                if nicon == '' and entry['Frame'].FriendLabel.Image ~= '' then
                    entry['Frame'].TitleFrame.Title.Position=entry['Frame'].TitleFrame.Title.Position-UDim2.new(0,17,0,0)
                elseif nicon ~= '' and entry['Frame'].FriendLabel.Image == '' then
                    entry['Frame'].TitleFrame.Title.Position=entry['Frame'].TitleFrame.Title.Position+UDim2.new(0,17,0,0)
                    debugprint('confirmed status:'..player.Name)
                end
                entry['Frame'].FriendLabel.Image = nicon
                return
            end
        end
    end)
end

# Line 2752 to 2759, only debugprint() is debug.
function RemoveNeutralTeam()
    while NeutralTeamLock do debugprint('in neutral team lock') wait() end 
    NeutralTeamLock = true
    NeutralTeam['Frame']:Destroy()
    NeutralTeam=nil
    RemoveMiddleBGFrame()
    NeutralTeamLock = false
end

# Line 2816 to 2824, only debugprint() is debug. Function does continue after this point, it doesn't end here.
--[[
    creates team entry and frame for this team, sets up listeners for this team
    adds any players intended for this team,Creates neutral team if this is the first team added
    Note:might be best to break this into multiple functions to simplify
    @Args:
    nteam   new team object added
--]]
function InsertTeamFrame(nteam) 
    while AddingFrameLock do debugprint('in adding team frame lock') wait(1/30) end 

# Line 2876 to 2907, only debugprint() is debug.
--[[
    removes team from team list
    @Args:
    nteam       Teamobject to remove
--]]
function RemoveTeamFrame(nteam)
    while AddingFrameLock do debugprint('in removing team frame lock') wait(1/30) end 
    AddingFrameLock = true
    if IsMinimized.Value then
    end
    local myEntry
    for i,key in ipairs(TeamFrames) do
        if nteam == key['MyTeam'] then
            myEntry = key
            key['Frame']:Destroy()
            table.remove(TeamFrames,i)
        end
    end
    if #TeamFrames==0 then
        debugprint('removeteamframe, remove neutral')
        if NeutralTeam then 
            RemoveNeutralTeam()
        end
    end
    for i,key in ipairs(myEntry['MyPlayers']) do
        RemovePlayerFromTeam(myEntry,i) 
        PlayerChanged(key, 'TeamColor')
    end
    RemoveMiddleBGFrame()
    BaseUpdate()
    AddingFrameLock = false
end

# Line 2916 to 2959, only debugprint() is debug. Function does continue after this point, it doesn't end here.
 --------------------------------- 
--[[
    called when ANYTHING changes the state of the playerlist
    re-sorts everything,assures correct positions of all elements
--]]
function BaseUpdate()
    while BaseUpdateLock do debugprint('in baseupdate lock') wait(1/30) end
    BaseUpdateLock = true
    --print ('baseupdate')
    UpdateStatNames()
    
    if #TeamFrames == 0 and not NeutralTeam then
        PlayerListModeUpdate()
    else
        TeamListModeUpdate()
    end
    for i,key in ipairs(MiddleFrames) do
        if key.Parent ~= nil then
            key.Position = UDim2.new(.5,0,((#MiddleFrames - (i)) * key.Size.Y.Scale),0)
        end
    end
    if not IsMinimized.Value and #MiddleFrames>DefaultEntriesOnScreen then
        UpdateScrollPosition()
    end
    
    UpdateMinimize()

    UpdateScrollBarSize()
    UpdateScrollPosition()

    UpdateScrollBarVisibility()
    --debugprint('EndBaseUpdate')
    BaseUpdateLock = false
end

--[[
    code for attaching tab key to maximizing player list
--]]
game.GuiService:AddKey("\t")
local LastTabTime = time()
game.GuiService.KeyPressed:connect(
function(key)
    if key == "\t" then
        debugprint('caught tab key')

# Line 2983 to 2989, only debugPlayerAdd() is debug.
function PlayersChildAdded(tplayer)
    if tplayer:IsA('Player') then 
        Spawn(function() debugPlayerAdd(tplayer) end) 
    else
        BlowThisPopsicleStand()
    end
end

# Line 3013 to 3018.
function PlayersChildAdded(tplayer)
    if tplayer:IsA('Player') then 
        Spawn(function() debugPlayerAdd(tplayer) end) 
    else
        BlowThisPopsicleStand()
    end
end

# Line 3025 to 3027, only debugPlayerAdd() is debug.
while not game:GetService('Teams') do wait(1/30) debugprint('Waiting For Teams') end
for _,i in pairs(game.Teams:GetTeams()) do TeamAdded(i) end
for _,i in pairs(Players:GetPlayers()) do Spawn(function() debugPlayerAdd(i) end) end

# Line 3043 to 3060, yes, this is the code from the picture! All of this is pure debug heaven!
 ----------------------------  
 -- Running Logic
 ---------------------------- 

 --debug stuffs, will only run for 'newplayerlistisbad'
 if LocalPlayer.Name == 'newplayerlistisbad' or LocalPlayer.Name == 'imtotallyadmin' then
    debugFrame.Parent = ScreenGui
    Spawn(function()
        while true do
            local str_players=''
            for _,i in pairs(game.Players:GetPlayers()) do
                str_players= str_players .." " .. i.Name
            end
            debugplayers.Text=str_players
            wait(.5)
        end
    end)
 end