-- Creates the generic "ROBLOX" loading screen on startup -- Written by ArceusInator & Ben Tkacheff, 2014 -- Updates by 0xBAADF00D, 2017 local AssetService = game:GetService("AssetService") local MarketplaceService = game:GetService("MarketplaceService") local UserInputService = game:GetService("UserInputService") local VRService = game:GetService("VRService") local GuiService = game:GetService("GuiService") local ContextActionService = game:GetService("ContextActionService") local RunService = game:GetService("RunService") local Players = game:GetService("Players") local ContentProvider = game:GetService("ContentProvider") local CoreGui = game:GetService("CoreGui") local ReplicatedFirst = game:GetService("ReplicatedFirst") local ScriptContext = game:GetService("ScriptContext") local RobloxGui = CoreGui:WaitForChild("RobloxGui") local create = require(RobloxGui:WaitForChild("Modules"):WaitForChild("Common"):WaitForChild("Create")) local PolicyService = require(RobloxGui.Modules.Common:WaitForChild("PolicyService")) --FFlags local FFlagLoadTheLoadingScreenFasterSuccess, FFlagLoadTheLoadingScreenFasterValue = pcall(function() return settings():GetFFlag("LoadTheLoadingScreenFaster") end) local FFlagLoadTheLoadingScreenFaster = FFlagLoadTheLoadingScreenFasterSuccess and FFlagLoadTheLoadingScreenFasterValue local FFlagLoadTheLoadingScreenEvenFaster = game:DefineFastFlag("LoadTheLoadingScreenEvenFaster", false) local FFlagLoadingScreenDontBlockOnPolicyService = game:DefineFastFlag("LoadingScreenDontBlockOnPolicyService", false) local FFlagBackButtonWhileLoadingGoesBackToApp = game:DefineFastFlag("BackButtonWhileLoadingGoesBackToApp", false) local FFlagShowConnectionErrorCode = settings():GetFFlag("ShowConnectionErrorCode") local FFlagConnectionScriptEnabled = settings():GetFFlag("ConnectionScriptEnabled") local antiAddictionNoticeStringEn = "Boycott bad games, refuse pirated games. Be aware of self-defense and being deceived. Playing games is good for your brain, but too much game play can harm your health. Manage your time well and enjoy a healthy lifestyle." local FFlagDisableAutoTranslateForKeyTranslatedContent = require(RobloxGui.Modules.Flags.FFlagDisableAutoTranslateForKeyTranslatedContent) local FFlagConnectErrorHandlerInLoadingScript = require(RobloxGui.Modules.Flags.FFlagConnectErrorHandlerInLoadingScript) local debugMode = false local startTime = tick() local loadingImageInputBeganConn = nil local waitForGameIdConnection local GAME_THUMBNAIL_URL = "rbxthumb://type=GameIcon&id=%d&w=256&h=256" local MAX_ICON_SIZE = Vector2.new(256, 256) local ICON_ASPECT_RATIO = 1 local COLORS = { BACKGROUND_COLOR = Color3.fromRGB(45, 45, 45), TEXT_COLOR = Color3.fromRGB(255, 255, 255), ERROR = Color3.fromRGB(253, 68, 72) } local spinnerImageId = "rbxasset://textures/loading/robloxTilt.png" -- Variables local GameAssetInfo -- loaded by InfoProvider:LoadAssets() local currScreenGui local renderSteppedConnection local backButtonConnection local destroyingBackground, destroyedLoadingGui = false, false local isTenFootInterface = GuiService:IsTenFootInterface() local placeLabel, creatorLabel = nil, nil local backgroundFadeStarted = false local tweenPlaceIcon = nil local layoutIsReady = false local connectionHealthShown = false local connectionHealthCon local InfoProvider = {} local function WaitForPlaceId() local placeId = game.PlaceId if placeId == 0 then game:GetPropertyChangedSignal("PlaceId"):wait() placeId = game.PlaceId end return placeId end function InfoProvider:GetGameName() if GameAssetInfo ~= nil then return GameAssetInfo.Name else return '' end end function InfoProvider:GetCreatorName() if GameAssetInfo ~= nil then return GameAssetInfo.Creator.Name else return '' end end function InfoProvider:LoadAssets() if FFlagLoadTheLoadingScreenFaster then coroutine.wrap(function() local placeId = WaitForPlaceId() local success, result = pcall(function() GameAssetInfo = MarketplaceService:GetProductInfo(placeId) end) if not success then print("LoadingScript->InfoProvider:LoadAssets:", result) end end)() else --spawn() == slowpoke.jpg spawn(function() local PLACEID = game.PlaceId if PLACEID <= 0 then while game.PlaceId <= 0 do wait() end PLACEID = game.PlaceId end -- load game asset info coroutine.resume(coroutine.create(function() local success, result = pcall(function() GameAssetInfo = MarketplaceService:GetProductInfo(PLACEID) end) if not success then print("LoadingScript->InfoProvider:LoadAssets:", result) end end)) end) end end -- create a cancel binding for console to be able to cancel anytime while loading local function createTenfootCancelGui() local cancelLabel = create'ImageLabel' { Name = "CancelLabel", Size = UDim2.new(0, 83, 0, 83), Position = UDim2.new(1, -32 - 83, 0, 32), BackgroundTransparency = 1, Image = 'rbxasset://textures/ui/Shell/ButtonIcons/BButton.png' } local cancelText = create'TextLabel' { Name = "CancelText", Size = UDim2.new(0, 400, 0, 83), Position = UDim2.new(1, -131, 0, 32), AnchorPoint = Vector2.new(1, 0), BackgroundTransparency = 1, Font = Enum.Font.SourceSans, TextSize = 48, TextXAlignment = Enum.TextXAlignment.Right, TextColor3 = COLORS.TEXT_COLOR, Text = "Cancel" } if not ReplicatedFirst:IsFinishedReplicating() then local seenBButtonBegin = false ContextActionService:BindCoreAction("CancelGameLoad", function(actionName, inputState, inputObject) if inputState == Enum.UserInputState.Begin then seenBButtonBegin = true elseif inputState == Enum.UserInputState.End and seenBButtonBegin then cancelLabel:Destroy() cancelText.Text = "Canceling..." cancelText.Position = UDim2.new(1, -32, 0, 32) ContextActionService:UnbindCoreAction('CancelGameLoad') game:Shutdown() end end, false, Enum.KeyCode.ButtonB) end while cancelLabel.Parent == nil do if currScreenGui then local blackFrame = currScreenGui:FindFirstChild('BlackFrame') if blackFrame then cancelLabel.Parent = blackFrame cancelText.Parent = blackFrame break end end wait() end end local function GenerateGui() local screenGui = create 'ScreenGui' { Name = 'RobloxLoadingGui', DisplayOrder = 8, } -- -- create descendant frames local mainBackgroundContainer local inGameGlobalGuiInset = settings():GetFVariable("InGameGlobalGuiInset") mainBackgroundContainer = create 'Frame' { Name = 'BlackFrame', BackgroundColor3 = COLORS.BACKGROUND_COLOR, BackgroundTransparency = 0, Size = UDim2.new(1, 0, 1, inGameGlobalGuiInset), Position = UDim2.new(0, 0, 0, -inGameGlobalGuiInset), Active = true, Parent = screenGui } local closeButton = create 'ImageButton' { Name = 'CloseButton', Image = 'rbxasset://textures/loading/cancelButton.png', ImageTransparency = 1, BackgroundTransparency = 1, Position = UDim2.new(1, -37, 0, 5), Size = UDim2.new(0, 32, 0, 32), Active = false, ZIndex = 10, Parent = mainBackgroundContainer } closeButton.MouseButton1Click:connect(function() game:Shutdown() end) local graphicsFrame = create 'Frame' { Name = 'GraphicsFrame', BorderSizePixel = 0, BackgroundTransparency = 1, AnchorPoint = Vector2.new(1, 1), Position = UDim2.new(0.95, 0, 0.95, 0), Size = UDim2.new(0.15, 0, 0.15, 0), ZIndex = 2, Parent = mainBackgroundContainer, create("UIAspectRatioConstraint") { AspectRatio = 1 }, create("UISizeConstraint") { MaxSize = Vector2.new(100, 100) } } local loadingImage = create 'ImageLabel' { Name = 'LoadingImage', BackgroundTransparency = 1, Image = spinnerImageId, AnchorPoint = Vector2.new(0.5, 0.5), Position = UDim2.new(0.5, 0, 0.5, 0), Size = UDim2.new(1, 0, 1, 0), ZIndex = 2, Parent = graphicsFrame, } local numberOfTaps = 0 local lastTapTime = math.huge local doubleTapTimeThreshold = 0.5 loadingImageInputBeganConn = loadingImage.InputBegan:connect(function() if PolicyService:IsSubjectToChinaPolicies() then return end if numberOfTaps == 0 then numberOfTaps = 1 lastTapTime = tick() return end if UserInputService.TouchEnabled == true and UserInputService.MouseEnabled == false then if tick() - lastTapTime <= doubleTapTimeThreshold then GuiService:ShowStatsBasedOnInputString("ConnectionHealth") connectionHealthShown = not connectionHealthShown end end numberOfTaps = 0 lastTapTime = math.huge end) local infoFrame = create 'Frame' { Name = 'InfoFrame', BackgroundTransparency = 1, AnchorPoint = Vector2.new(0.5, 0.5), Position = UDim2.new(0.5, 0, 0.5, 0), Size = UDim2.new(0.75, 0, 1, 0), ZIndex = 2, Parent = mainBackgroundContainer, create 'UIPadding' { Name = 'UiMessagePadding', PaddingBottom = UDim.new(0, 25), } or nil } local uiMessageFrame = create 'Frame' { Name = 'UiMessageFrame', BackgroundTransparency = 1, Position = UDim2.new(0.25, 0, 1, -120), Size = UDim2.new(1, 0, 0, 35), ZIndex = 2, LayoutOrder = 5, Parent = infoFrame, create 'TextLabel' { Name = 'UiMessage', BackgroundTransparency = 1, Position = UDim2.new(0, 0, 0, 5), Size = UDim2.new(1, 0, 0, 25), Font = Enum.Font.SourceSansLight, TextSize = 18, TextScaled = true, TextWrapped = true, TextColor3 = COLORS.TEXT_COLOR, Text = "", TextTransparency = 1, ZIndex = 2, } } local infoFrameAspect = create("UIAspectRatioConstraint") { AspectRatio = 3 / 2, Parent = infoFrame } local infoFrameList = create("UIListLayout") { SortOrder = Enum.SortOrder.LayoutOrder, FillDirection = Enum.FillDirection.Vertical, VerticalAlignment = Enum.VerticalAlignment.Center, HorizontalAlignment = Enum.HorizontalAlignment.Center, Padding = UDim.new(0.05, 0), Parent = infoFrame } local textContainer = create("Frame") { BackgroundTransparency = 1, Size = UDim2.new(2/3, 0, 1, 0), LayoutOrder = 2, Parent = nil, create("UIListLayout") { FillDirection = Enum.FillDirection.Vertical, VerticalAlignment = Enum.VerticalAlignment.Center, HorizontalAlignment = Enum.HorizontalAlignment.Left, SortOrder = Enum.SortOrder.LayoutOrder } } local placeIcon = create("ImageLabel") { Name = "PlaceIcon", BackgroundTransparency = 1, Size = UDim2.new(1, 0, 1, 0), Position = UDim2.new(0.5, 0, 0, 0), AnchorPoint = Vector2.new(0.5, 0), LayoutOrder = 1, Parent = infoFrame, ImageTransparency = 1, Image = "", create("UIAspectRatioConstraint") { AspectRatio = FFlagLoadTheLoadingScreenEvenFaster and ICON_ASPECT_RATIO or 576 / 324, AspectType = Enum.AspectType.ScaleWithParentSize, DominantAxis = Enum.DominantAxis.Width }, create("UISizeConstraint") { MaxSize = FFlagLoadTheLoadingScreenEvenFaster and MAX_ICON_SIZE or Vector2.new(400, 400) } } if FFlagLoadTheLoadingScreenEvenFaster then local function onGameId() local gameId = game.GameId local imageUrl = GAME_THUMBNAIL_URL:format(gameId) placeIcon.Image = imageUrl ContentProvider:PreloadAsync({ placeIcon }) if not backgroundFadeStarted then placeIcon.ImageTransparency = 0 end end if game.GameId > 0 then coroutine.wrap(onGameId)() else waitForGameIdConnection = game:GetPropertyChangedSignal("GameId"):Connect(function () waitForGameIdConnection:Disconnect() onGameId() end) end else --Start trying to load the place icon image --Web might not have this icon size generated, so we can poll asset-thumbnail/json and check --the JSON result for thumbnailFinal/Final to see when it's done being generated so we never --show a N/A image. This is how the console AppShell does it! coroutine.wrap(function() local placeId = WaitForPlaceId() local function tryGetFinalAsync() local imageUrl = nil local isGenerated = false local success, msg = pcall(function() imageUrl, isGenerated = AssetService:GetAssetThumbnailAsync(placeId, Vector2.new(576, 324), 1) end) if success and isGenerated == true and imageUrl then ContentProvider:PreloadAsync { imageUrl } placeIcon.Image = imageUrl if not backgroundFadeStarted then placeIcon.ImageTransparency = 0 end return true end return false end while not tryGetFinalAsync() do end end)() end placeLabel = create 'TextLabel' { Name = 'PlaceLabel', BackgroundTransparency = 1, Size = UDim2.new(1, 0, 0, 80), Position = UDim2.new(0, 0, 0, 0), Font = Enum.Font.SourceSans, TextSize = isTenFootInterface and 48 or 24, TextWrapped = true, TextScaled = true, TextColor3 = COLORS.TEXT_COLOR, TextStrokeTransparency = 1, TextTransparency = 1, Text = "", TextXAlignment = Enum.TextXAlignment.Center, TextYAlignment = Enum.TextYAlignment.Bottom, ZIndex = 2, LayoutOrder = 2, Parent = infoFrame } local creatorContainer = create 'Frame' { Name = "Creator", BackgroundTransparency = 1, Size = UDim2.new(1, 0, 0, 48), LayoutOrder = 3, create 'UIListLayout' { FillDirection = Enum.FillDirection.Horizontal, HorizontalAlignment = Enum.HorizontalAlignment.Center, VerticalAlignment = Enum.VerticalAlignment.Center, SortOrder = Enum.SortOrder.LayoutOrder, Padding = UDim.new(0, 5) } } local byLabel, creatorIcon = nil, nil if isTenFootInterface then byLabel = create'TextLabel' { Name = "ByLabel", BackgroundTransparency = 1, Size = UDim2.new(0, 36, 0, 30), Position = UDim2.new(0, 0, 0, 80), Font = Enum.Font.SourceSansLight, TextSize = 36, TextScaled = true, TextColor3 = COLORS.TEXT_COLOR, TextStrokeTransparency = 1, Text = "By", TextXAlignment = Enum.TextXAlignment.Left, TextYAlignment = Enum.TextYAlignment.Top, ZIndex = 2, Visible = true, Parent = infoFrame, LayoutOrder = 1 } creatorIcon = create'ImageLabel' { Name = "CreatorIcon", BackgroundTransparency = 1, Size = UDim2.new(0, 30, 0, 30), Position = UDim2.new(0, 38, 0, 80), ImageTransparency = 0, Image = 'rbxasset://textures/ui/Shell/Icons/RobloxIcon24.png', ZIndex = 2, Visible = true, Parent = infoFrame, LayoutOrder = 2 } end creatorLabel = create 'TextLabel' { Name = 'CreatorLabel', BackgroundTransparency = 1, Size = UDim2.new(1, 0, 0, 30), Position = UDim2.new(0, 0, 0, 80), Font = Enum.Font.SourceSansLight, TextSize = isTenFootInterface and 36 or 18, TextWrapped = true, TextScaled = true, TextColor3 = COLORS.TEXT_COLOR, TextStrokeTransparency = 1, Text = "", TextXAlignment = Enum.TextXAlignment.Center, TextYAlignment = Enum.TextYAlignment.Center, ZIndex = 2, LayoutOrder = 4, Parent = infoFrame } if isTenFootInterface then creatorContainer.Parent = infoFrame byLabel.TextScaled = false byLabel.Parent = creatorContainer byLabel.TextXAlignment = Enum.TextXAlignment.Center byLabel.TextYAlignment = Enum.TextYAlignment.Center creatorIcon.Parent = creatorContainer creatorLabel.Parent = creatorContainer creatorLabel.TextScaled = false creatorLabel.TextWrapped = false creatorLabel.Position = UDim2.new(0, 72, 0, 80) creatorLabel.Size = UDim2.new(0, creatorLabel.TextBounds.X, 1, 0) end coroutine.wrap(function() RunService.RenderStepped:wait() RunService.RenderStepped:wait() layoutIsReady = true placeLabel.TextTransparency = 0 local uiMessage = uiMessageFrame.UiMessage if uiMessage.Text ~= "" then uiMessage.TextTransparency = 0 end end)() if not FFlagConnectionScriptEnabled or isTenFootInterface then local errorFrame = create 'Frame' { Name = 'ErrorFrame', BackgroundColor3 = COLORS.ERROR, BorderSizePixel = 0, Position = UDim2.new(0.25,0,0,0), Size = UDim2.new(0.5, 0, 0, 80), ZIndex = 8, Visible = false, Parent = screenGui, create 'TextLabel' { Name = "ErrorText", BackgroundTransparency = 1, Size = UDim2.new(1, 0, 1, 0), Font = Enum.Font.SourceSansBold, TextSize = 14, TextWrapped = true, TextColor3 = COLORS.TEXT_COLOR, Text = "", ZIndex = 8 } } else if FFlagConnectErrorHandlerInLoadingScript then ScriptContext:AddCoreScriptLocal("Connection", RobloxGui) end end while not game:GetService("CoreGui") do if FFlagLoadTheLoadingScreenFaster then RunService.RenderStepped:wait() else wait() end end screenGui.Parent = CoreGui infoFrame.RootLocalizationTable = CoreGui:FindFirstChild("CoreScriptLocalization") currScreenGui = screenGui local function onResized() local isPortrait = screenGui.AbsoluteSize.X < screenGui.AbsoluteSize.Y infoFrame.Position = UDim2.new(0.5, 0, 0.5, 0) infoFrame.AnchorPoint = Vector2.new(0.5, 0.5) infoFrame.Size = UDim2.new(0.75, 0, 1, 0) infoFrameAspect.AspectRatio = isPortrait and 2/3 or 3/2 placeLabel.Size = UDim2.new(1, 0, 0, isTenFootInterface and 120 or 80) if isTenFootInterface then creatorLabel.Size = UDim2.new(0, creatorLabel.TextBounds.X, 1, 0) else creatorLabel.Size = UDim2.new(1, 0, 0, 30) end infoFrameList.FillDirection = Enum.FillDirection.Vertical infoFrameList.HorizontalAlignment = Enum.HorizontalAlignment.Center infoFrameList.Padding = UDim.new(0, 0) textContainer.Parent = nil infoFrameList:ApplyLayout() placeLabel.TextXAlignment = Enum.TextXAlignment.Center placeLabel.AutoLocalize = not FFlagDisableAutoTranslateForKeyTranslatedContent end onResized() screenGui:GetPropertyChangedSignal("AbsoluteSize"):connect(onResized) end --------------------------------------------------------- -- Main Script (show something now + setup connections) -- start loading assets asap InfoProvider:LoadAssets() GenerateGui() if isTenFootInterface then createTenfootCancelGui() end local fadeCycleTime = 1.7 local turnCycleTime = 2 local function spinnerEasingFunc(a, b, t) t = t * 2 if t < 1 then return b / 2 * t*t*t + a else t = t - 2 return b / 2 * (t * t * t + 2) + b end end if FFlagLoadingScreenDontBlockOnPolicyService then local showAntiAddictionNoticeStringEn = false -- PolicyService requires LocalPlayer to exist, which doesn't happen until -- after we connect to the server. If the server is full, this can take a -- very long time (like several minutes) to return a value. As a result, we -- call it asynchronously and default to false. coroutine.wrap(function() showAntiAddictionNoticeStringEn = PolicyService:IsSubjectToChinaPolicies() end)() renderSteppedConnection = RunService.RenderStepped:connect(function(dt) if not currScreenGui then return end if not currScreenGui:FindFirstChild("BlackFrame") then return end local infoFrame = currScreenGui.BlackFrame:FindFirstChild('InfoFrame') if infoFrame then -- set place name if placeLabel and placeLabel.Text == "" then placeLabel.Text = InfoProvider:GetGameName() end -- set creator name if creatorLabel and creatorLabel.Text == "" then if showAntiAddictionNoticeStringEn then creatorLabel.Text = antiAddictionNoticeStringEn else local creatorName = InfoProvider:GetCreatorName() if creatorName ~= "" then if isTenFootInterface then creatorLabel.Text = creatorName creatorLabel.Size = UDim2.new(0, creatorLabel.TextBounds.X, 1, 0) else creatorLabel.Text = "By ".. creatorName end end end end end local currentTime = tick() local fadeAmount = dt * fadeCycleTime local spinnerImage = currScreenGui.BlackFrame.GraphicsFrame.LoadingImage local timeInCycle = currentTime % turnCycleTime local cycleAlpha = spinnerEasingFunc(0, 1, timeInCycle / turnCycleTime) spinnerImage.Rotation = cycleAlpha * 360 if not isTenFootInterface then if currentTime - startTime > 5 and currScreenGui.BlackFrame.CloseButton.ImageTransparency > 0 then currScreenGui.BlackFrame.CloseButton.ImageTransparency = currScreenGui.BlackFrame.CloseButton.ImageTransparency - fadeAmount if currScreenGui.BlackFrame.CloseButton.ImageTransparency <= 0 then currScreenGui.BlackFrame.CloseButton.Active = true end end end end) else coroutine.wrap(function() local showAntiAddictionNoticeStringEn = PolicyService:IsSubjectToChinaPolicies() renderSteppedConnection = RunService.RenderStepped:connect(function(dt) if not currScreenGui then return end if not currScreenGui:FindFirstChild("BlackFrame") then return end local infoFrame = currScreenGui.BlackFrame:FindFirstChild('InfoFrame') if infoFrame then -- set place name if placeLabel and placeLabel.Text == "" then placeLabel.Text = InfoProvider:GetGameName() end -- set creator name if creatorLabel and creatorLabel.Text == "" then if showAntiAddictionNoticeStringEn then creatorLabel.Text = antiAddictionNoticeStringEn else local creatorName = InfoProvider:GetCreatorName() if creatorName ~= "" then if isTenFootInterface then creatorLabel.Text = creatorName creatorLabel.Size = UDim2.new(0, creatorLabel.TextBounds.X, 1, 0) else creatorLabel.Text = "By ".. creatorName end end end end end local currentTime = tick() local fadeAmount = dt * fadeCycleTime local spinnerImage = currScreenGui.BlackFrame.GraphicsFrame.LoadingImage local timeInCycle = currentTime % turnCycleTime local cycleAlpha = spinnerEasingFunc(0, 1, timeInCycle / turnCycleTime) spinnerImage.Rotation = cycleAlpha * 360 if not isTenFootInterface then if currentTime - startTime > 5 and currScreenGui.BlackFrame.CloseButton.ImageTransparency > 0 then currScreenGui.BlackFrame.CloseButton.ImageTransparency = currScreenGui.BlackFrame.CloseButton.ImageTransparency - fadeAmount if currScreenGui.BlackFrame.CloseButton.ImageTransparency <= 0 then currScreenGui.BlackFrame.CloseButton.Active = true end end end end) end)() end -- use the old error frame when on XBox if not FFlagConnectionScriptEnabled or isTenFootInterface then local errorImage GuiService.ErrorMessageChanged:connect(function() if GuiService:GetErrorMessage() ~= '' then --TODO: Remove this reference to Utility local utility = require(RobloxGui.Modules.Settings.Utility) if isTenFootInterface then currScreenGui.ErrorFrame.Size = UDim2.new(1, 0, 0, 144) currScreenGui.ErrorFrame.Position = UDim2.new(0, 0, 0, 0) currScreenGui.ErrorFrame.BackgroundColor3 = COLORS.BACKGROUND_COLOR currScreenGui.ErrorFrame.BackgroundTransparency = 0.5 currScreenGui.ErrorFrame.ErrorText.TextSize = 36 currScreenGui.ErrorFrame.ErrorText.Position = UDim2.new(.3, 0, 0, 0) currScreenGui.ErrorFrame.ErrorText.Size = UDim2.new(.4, 0, 0, 144) if errorImage == nil then errorImage = Instance.new("ImageLabel") errorImage.Image = "rbxasset://textures/ui/ErrorIconSmall.png" errorImage.Size = UDim2.new(0, 96, 0, 79) errorImage.Position = UDim2.new(0.228125, 0, 0, 32) errorImage.ZIndex = 9 errorImage.BackgroundTransparency = 1 errorImage.Parent = currScreenGui.ErrorFrame end elseif utility:IsSmallTouchScreen() then currScreenGui.ErrorFrame.Size = UDim2.new(0.5, 0, 0, 40) end local errorCode = GuiService:GetErrorCode() local errorMessage = GuiService:GetErrorMessage() if not FFlagShowConnectionErrorCode then currScreenGui.ErrorFrame.ErrorText.Text = errorMessage else if not errorCode then currScreenGui.ErrorFrame.ErrorText.Text = ("%s (Error Code: -1)"):format(errorMessage) else currScreenGui.ErrorFrame.ErrorText.Text = ("%s (Error Code: %d)"):format(errorMessage, errorCode.Value) end end currScreenGui.ErrorFrame.Visible = true local blackFrame = currScreenGui:FindFirstChild('BlackFrame') if blackFrame then blackFrame.CloseButton.ImageTransparency = 0 blackFrame.CloseButton.Active = true end else currScreenGui.ErrorFrame.Visible = false end end) end if FFlagBackButtonWhileLoadingGoesBackToApp then backButtonConnection = GuiService.ShowLeaveConfirmation:Connect(function() -- When OS back button is pressed during loading screen, exit -- immediately. Behaves the same as the close button. game:Shutdown() end) end GuiService.UiMessageChanged:connect(function(type, newMessage) if type == Enum.UiMessageType.UiMessageInfo then local blackFrame = currScreenGui and currScreenGui:FindFirstChild('BlackFrame') if blackFrame then local infoFrame = blackFrame:FindFirstChild("InfoFrame") if infoFrame then local uiMessage = infoFrame.UiMessageFrame.UiMessage uiMessage.Text = newMessage if newMessage ~= '' and layoutIsReady then uiMessage.TextTransparency = 0 else uiMessage.TextTransparency = 1 end end end end end) if not FFlagConnectionScriptEnabled and GuiService:GetErrorMessage() ~= '' then currScreenGui.ErrorFrame.ErrorText.Text = GuiService:GetErrorMessage() currScreenGui.ErrorFrame.Visible = true end local function stopListeningToRenderingStep() if renderSteppedConnection then renderSteppedConnection:disconnect() renderSteppedConnection = nil end end local function disconnectAndCloseHealthStat() if connectionHealthCon then connectionHealthCon:disconnect() connectionHealthCon = nil GuiService:CloseStatsBasedOnInputString("ConnectionHealth") end end local function fadeAndDestroyBlackFrame(blackFrame) if destroyingBackground then return end destroyingBackground = true spawn(function() local infoFrame = blackFrame:FindFirstChild("InfoFrame") local graphicsFrame = blackFrame:FindFirstChild("GraphicsFrame") local infoFrameDescendants = infoFrame:GetDescendants() local transparency = 0 local rateChange = 1.8 local lastUpdateTime = nil --Notify everything else to stop messing with transparency to avoid ugly fighting effects backgroundFadeStarted = true if tweenPlaceIcon then tweenPlaceIcon:Cancel() tweenPlaceIcon = nil end while transparency < 1 do RunService.RenderStepped:wait() if not lastUpdateTime then lastUpdateTime = tick() else local newTime = tick() transparency = transparency + rateChange * (newTime - lastUpdateTime) for i = 1, #infoFrameDescendants do local child = infoFrameDescendants[i] if child:IsA('TextLabel') then child.TextTransparency = transparency elseif child:IsA('ImageLabel') then child.ImageTransparency = transparency end end graphicsFrame.LoadingImage.ImageTransparency = transparency blackFrame.BackgroundTransparency = transparency lastUpdateTime = newTime end end if blackFrame ~= nil then stopListeningToRenderingStep() blackFrame:Destroy() end if waitForGameIdConnection then waitForGameIdConnection:Disconnect() end if loadingImageInputBeganConn then loadingImageInputBeganConn:disconnect() end if backButtonConnection then backButtonConnection:Disconnect() end if connectionHealthShown then if UserInputService.TouchEnabled == true and UserInputService.MouseEnabled == false then connectionHealthCon = game:GetService("UserInputService").InputBegan:connect(function() disconnectAndCloseHealthStat() end) else GuiService:CloseStatsBasedOnInputString("ConnectionHealth") end else GuiService:CloseStatsBasedOnInputString("ConnectionHealth") end end) end local function destroyLoadingElements(instant) if not currScreenGui then return end if destroyedLoadingGui then return end destroyedLoadingGui = true local guiChildren = currScreenGui:GetChildren() for i=1, #guiChildren do -- need to keep this around in case we get a connection error later if guiChildren[i].Name ~= "ErrorFrame" then if guiChildren[i].Name == "BlackFrame" and not instant then fadeAndDestroyBlackFrame(guiChildren[i]) else guiChildren[i]:Destroy() end end end end local function waitForCharacterLoaded() if Players.CharacterAutoLoads then local localPlayer = Players.LocalPlayer if not localPlayer then Players:GetPropertyChangedSignal("LocalPlayer"):wait() localPlayer = Players.LocalPlayer end if not localPlayer.Character then localPlayer.CharacterAdded:wait() end end end local function handleRemoveDefaultLoadingGui(instant) if isTenFootInterface then ContextActionService:UnbindCoreAction('CancelGameLoad') end destroyLoadingElements(instant) ReplicatedFirst:SetDefaultLoadingGuiRemoved() end local function handleFinishedReplicating() if #ReplicatedFirst:GetChildren() == 0 then if game:IsLoaded() then waitForCharacterLoaded() handleRemoveDefaultLoadingGui() else local gameLoadedCon = nil gameLoadedCon = game.Loaded:connect(function() gameLoadedCon:disconnect() gameLoadedCon = nil waitForCharacterLoaded() handleRemoveDefaultLoadingGui() end) end else wait(5) -- make sure after 5 seconds we remove the default gui, even if the user doesn't handleRemoveDefaultLoadingGui() end end if debugMode then warn("Not destroying loading screen because debugMode is true") return end ReplicatedFirst.FinishedReplicating:connect(handleFinishedReplicating) if ReplicatedFirst:IsFinishedReplicating() then handleFinishedReplicating() end ReplicatedFirst.RemoveDefaultLoadingGuiSignal:connect(handleRemoveDefaultLoadingGui) if ReplicatedFirst:IsDefaultLoadingGuiRemoved() then handleRemoveDefaultLoadingGui() end coroutine.wrap(function() if not VRService.VREnabled then VRService:GetPropertyChangedSignal("VREnabled"):Wait() end handleRemoveDefaultLoadingGui(true) require(RobloxGui.Modules.LoadingScreen3D) end)()